155714Skris/* crypto/asn1/t_x509.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/buffer.h>
6255714Skris#include <openssl/bn.h>
63109998Smarkm#ifndef OPENSSL_NO_RSA
64296341Sdelphij# include <openssl/rsa.h>
6555714Skris#endif
66109998Smarkm#ifndef OPENSSL_NO_DSA
67296341Sdelphij# include <openssl/dsa.h>
6855714Skris#endif
69160814Ssimon#ifndef OPENSSL_NO_EC
70296341Sdelphij# include <openssl/ec.h>
71160814Ssimon#endif
7255714Skris#include <openssl/objects.h>
7355714Skris#include <openssl/x509.h>
7455714Skris#include <openssl/x509v3.h>
75238405Sjkim#include "asn1_locl.h"
7655714Skris
77109998Smarkm#ifndef OPENSSL_NO_FP_API
7855714Skrisint X509_print_fp(FILE *fp, X509 *x)
79296341Sdelphij{
80296341Sdelphij    return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
81296341Sdelphij}
82109998Smarkm
83296341Sdelphijint X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
84296341Sdelphij                     unsigned long cflag)
85296341Sdelphij{
86296341Sdelphij    BIO *b;
87296341Sdelphij    int ret;
8855714Skris
89296341Sdelphij    if ((b = BIO_new(BIO_s_file())) == NULL) {
90296341Sdelphij        X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
91296341Sdelphij        return (0);
92296341Sdelphij    }
93296341Sdelphij    BIO_set_fp(b, fp, BIO_NOCLOSE);
94296341Sdelphij    ret = X509_print_ex(b, x, nmflag, cflag);
95296341Sdelphij    BIO_free(b);
96296341Sdelphij    return (ret);
97296341Sdelphij}
9855714Skris#endif
9955714Skris
10055714Skrisint X509_print(BIO *bp, X509 *x)
101109998Smarkm{
102296341Sdelphij    return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
103109998Smarkm}
104109998Smarkm
105296341Sdelphijint X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
106296341Sdelphij                  unsigned long cflag)
107296341Sdelphij{
108296341Sdelphij    long l;
109296341Sdelphij    int ret = 0, i;
110296341Sdelphij    char *m = NULL, mlch = ' ';
111296341Sdelphij    int nmindent = 0;
112296341Sdelphij    X509_CINF *ci;
113296341Sdelphij    ASN1_INTEGER *bs;
114296341Sdelphij    EVP_PKEY *pkey = NULL;
115296341Sdelphij    const char *neg;
11655714Skris
117296341Sdelphij    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
118296341Sdelphij        mlch = '\n';
119296341Sdelphij        nmindent = 12;
120296341Sdelphij    }
121109998Smarkm
122296341Sdelphij    if (nmflags == X509_FLAG_COMPAT)
123296341Sdelphij        nmindent = 16;
124109998Smarkm
125296341Sdelphij    ci = x->cert_info;
126296341Sdelphij    if (!(cflag & X509_FLAG_NO_HEADER)) {
127296341Sdelphij        if (BIO_write(bp, "Certificate:\n", 13) <= 0)
128296341Sdelphij            goto err;
129296341Sdelphij        if (BIO_write(bp, "    Data:\n", 10) <= 0)
130296341Sdelphij            goto err;
131296341Sdelphij    }
132296341Sdelphij    if (!(cflag & X509_FLAG_NO_VERSION)) {
133296341Sdelphij        l = X509_get_version(x);
134296341Sdelphij        if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
135296341Sdelphij            goto err;
136296341Sdelphij    }
137296341Sdelphij    if (!(cflag & X509_FLAG_NO_SERIAL)) {
13855714Skris
139296341Sdelphij        if (BIO_write(bp, "        Serial Number:", 22) <= 0)
140296341Sdelphij            goto err;
141109998Smarkm
142296341Sdelphij        bs = X509_get_serialNumber(x);
143296341Sdelphij        if (bs->length <= (int)sizeof(long)) {
144296341Sdelphij            l = ASN1_INTEGER_get(bs);
145296341Sdelphij            if (bs->type == V_ASN1_NEG_INTEGER) {
146296341Sdelphij                l = -l;
147296341Sdelphij                neg = "-";
148296341Sdelphij            } else
149296341Sdelphij                neg = "";
150296341Sdelphij            if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
151296341Sdelphij                goto err;
152296341Sdelphij        } else {
153296341Sdelphij            neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
154296341Sdelphij            if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
155296341Sdelphij                goto err;
15655714Skris
157296341Sdelphij            for (i = 0; i < bs->length; i++) {
158296341Sdelphij                if (BIO_printf(bp, "%02x%c", bs->data[i],
159296341Sdelphij                               ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
160296341Sdelphij                    goto err;
161296341Sdelphij            }
162296341Sdelphij        }
16355714Skris
164296341Sdelphij    }
16555714Skris
166296341Sdelphij    if (!(cflag & X509_FLAG_NO_SIGNAME)) {
167296341Sdelphij        if (X509_signature_print(bp, ci->signature, NULL) <= 0)
168296341Sdelphij            goto err;
169238405Sjkim#if 0
170296341Sdelphij        if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0)
171296341Sdelphij            goto err;
172296341Sdelphij        if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
173296341Sdelphij            goto err;
174296341Sdelphij        if (BIO_puts(bp, "\n") <= 0)
175296341Sdelphij            goto err;
176238405Sjkim#endif
177296341Sdelphij    }
178109998Smarkm
179296341Sdelphij    if (!(cflag & X509_FLAG_NO_ISSUER)) {
180296341Sdelphij        if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
181296341Sdelphij            goto err;
182296341Sdelphij        if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
183296341Sdelphij            < 0)
184296341Sdelphij            goto err;
185296341Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
186296341Sdelphij            goto err;
187296341Sdelphij    }
188296341Sdelphij    if (!(cflag & X509_FLAG_NO_VALIDITY)) {
189296341Sdelphij        if (BIO_write(bp, "        Validity\n", 17) <= 0)
190296341Sdelphij            goto err;
191296341Sdelphij        if (BIO_write(bp, "            Not Before: ", 24) <= 0)
192296341Sdelphij            goto err;
193296341Sdelphij        if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
194296341Sdelphij            goto err;
195296341Sdelphij        if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
196296341Sdelphij            goto err;
197296341Sdelphij        if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
198296341Sdelphij            goto err;
199296341Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
200296341Sdelphij            goto err;
201296341Sdelphij    }
202296341Sdelphij    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
203296341Sdelphij        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
204296341Sdelphij            goto err;
205296341Sdelphij        if (X509_NAME_print_ex
206296341Sdelphij            (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
207296341Sdelphij            goto err;
208296341Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
209296341Sdelphij            goto err;
210296341Sdelphij    }
211296341Sdelphij    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
212296341Sdelphij        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
213296341Sdelphij            goto err;
214296341Sdelphij        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
215296341Sdelphij            goto err;
216296341Sdelphij        if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
217296341Sdelphij            goto err;
218296341Sdelphij        if (BIO_puts(bp, "\n") <= 0)
219296341Sdelphij            goto err;
22055714Skris
221296341Sdelphij        pkey = X509_get_pubkey(x);
222296341Sdelphij        if (pkey == NULL) {
223296341Sdelphij            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
224296341Sdelphij            ERR_print_errors(bp);
225296341Sdelphij        } else {
226296341Sdelphij            EVP_PKEY_print_public(bp, pkey, 16, NULL);
227296341Sdelphij            EVP_PKEY_free(pkey);
228296341Sdelphij        }
229296341Sdelphij    }
23055714Skris
231296341Sdelphij    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
232296341Sdelphij        X509V3_extensions_print(bp, "X509v3 extensions",
233296341Sdelphij                                ci->extensions, cflag, 8);
23455714Skris
235296341Sdelphij    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
236296341Sdelphij        if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
237296341Sdelphij            goto err;
238296341Sdelphij    }
239296341Sdelphij    if (!(cflag & X509_FLAG_NO_AUX)) {
240296341Sdelphij        if (!X509_CERT_AUX_print(bp, x->aux, 0))
241296341Sdelphij            goto err;
242296341Sdelphij    }
243296341Sdelphij    ret = 1;
244296341Sdelphij err:
245296341Sdelphij    if (m != NULL)
246296341Sdelphij        OPENSSL_free(m);
247296341Sdelphij    return (ret);
248296341Sdelphij}
24955714Skris
250296341Sdelphijint X509_ocspid_print(BIO *bp, X509 *x)
251296341Sdelphij{
252296341Sdelphij    unsigned char *der = NULL;
253296341Sdelphij    unsigned char *dertmp;
254296341Sdelphij    int derlen;
255296341Sdelphij    int i;
256296341Sdelphij    unsigned char SHA1md[SHA_DIGEST_LENGTH];
257109998Smarkm
258296341Sdelphij    /*
259296341Sdelphij     * display the hash of the subject as it would appear in OCSP requests
260296341Sdelphij     */
261296341Sdelphij    if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
262296341Sdelphij        goto err;
263296341Sdelphij    derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
264296341Sdelphij    if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL)
265296341Sdelphij        goto err;
266296341Sdelphij    i2d_X509_NAME(x->cert_info->subject, &dertmp);
267109998Smarkm
268296341Sdelphij    if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
269296341Sdelphij        goto err;
270296341Sdelphij    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
271296341Sdelphij        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
272296341Sdelphij            goto err;
273296341Sdelphij    }
274296341Sdelphij    OPENSSL_free(der);
275296341Sdelphij    der = NULL;
276109998Smarkm
277296341Sdelphij    /*
278296341Sdelphij     * display the hash of the public key as it would appear in OCSP requests
279296341Sdelphij     */
280296341Sdelphij    if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
281296341Sdelphij        goto err;
282109998Smarkm
283296341Sdelphij    if (!EVP_Digest(x->cert_info->key->public_key->data,
284296341Sdelphij                    x->cert_info->key->public_key->length,
285296341Sdelphij                    SHA1md, NULL, EVP_sha1(), NULL))
286296341Sdelphij        goto err;
287296341Sdelphij    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
288296341Sdelphij        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
289296341Sdelphij            goto err;
290296341Sdelphij    }
291296341Sdelphij    BIO_printf(bp, "\n");
292109998Smarkm
293296341Sdelphij    return (1);
294296341Sdelphij err:
295296341Sdelphij    if (der != NULL)
296296341Sdelphij        OPENSSL_free(der);
297296341Sdelphij    return (0);
298296341Sdelphij}
299109998Smarkm
300238405Sjkimint X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
301109998Smarkm{
302296341Sdelphij    const unsigned char *s;
303296341Sdelphij    int i, n;
304109998Smarkm
305296341Sdelphij    n = sig->length;
306296341Sdelphij    s = sig->data;
307296341Sdelphij    for (i = 0; i < n; i++) {
308296341Sdelphij        if ((i % 18) == 0) {
309296341Sdelphij            if (BIO_write(bp, "\n", 1) <= 0)
310296341Sdelphij                return 0;
311296341Sdelphij            if (BIO_indent(bp, indent, indent) <= 0)
312296341Sdelphij                return 0;
313296341Sdelphij        }
314296341Sdelphij        if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
315296341Sdelphij            return 0;
316296341Sdelphij    }
317296341Sdelphij    if (BIO_write(bp, "\n", 1) != 1)
318296341Sdelphij        return 0;
319238405Sjkim
320296341Sdelphij    return 1;
321109998Smarkm}
322109998Smarkm
323238405Sjkimint X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
324238405Sjkim{
325296341Sdelphij    int sig_nid;
326296341Sdelphij    if (BIO_puts(bp, "    Signature Algorithm: ") <= 0)
327296341Sdelphij        return 0;
328296341Sdelphij    if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
329296341Sdelphij        return 0;
330238405Sjkim
331296341Sdelphij    sig_nid = OBJ_obj2nid(sigalg->algorithm);
332296341Sdelphij    if (sig_nid != NID_undef) {
333296341Sdelphij        int pkey_nid, dig_nid;
334296341Sdelphij        const EVP_PKEY_ASN1_METHOD *ameth;
335296341Sdelphij        if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
336296341Sdelphij            ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
337296341Sdelphij            if (ameth && ameth->sig_print)
338296341Sdelphij                return ameth->sig_print(bp, sigalg, sig, 9, 0);
339296341Sdelphij        }
340296341Sdelphij    }
341296341Sdelphij    if (sig)
342296341Sdelphij        return X509_signature_dump(bp, sig, 9);
343296341Sdelphij    else if (BIO_puts(bp, "\n") <= 0)
344296341Sdelphij        return 0;
345296341Sdelphij    return 1;
346238405Sjkim}
347238405Sjkim
348238405Sjkimint ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
349296341Sdelphij{
350296341Sdelphij    int i, n;
351296341Sdelphij    char buf[80];
352296341Sdelphij    const char *p;
35355714Skris
354296341Sdelphij    if (v == NULL)
355296341Sdelphij        return (0);
356296341Sdelphij    n = 0;
357296341Sdelphij    p = (const char *)v->data;
358296341Sdelphij    for (i = 0; i < v->length; i++) {
359296341Sdelphij        if ((p[i] > '~') || ((p[i] < ' ') &&
360296341Sdelphij                             (p[i] != '\n') && (p[i] != '\r')))
361296341Sdelphij            buf[n] = '.';
362296341Sdelphij        else
363296341Sdelphij            buf[n] = p[i];
364296341Sdelphij        n++;
365296341Sdelphij        if (n >= 80) {
366296341Sdelphij            if (BIO_write(bp, buf, n) <= 0)
367296341Sdelphij                return (0);
368296341Sdelphij            n = 0;
369296341Sdelphij        }
370296341Sdelphij    }
371296341Sdelphij    if (n > 0)
372296341Sdelphij        if (BIO_write(bp, buf, n) <= 0)
373296341Sdelphij            return (0);
374296341Sdelphij    return (1);
375296341Sdelphij}
37655714Skris
377238405Sjkimint ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
37855714Skris{
379296341Sdelphij    if (tm->type == V_ASN1_UTCTIME)
380296341Sdelphij        return ASN1_UTCTIME_print(bp, tm);
381296341Sdelphij    if (tm->type == V_ASN1_GENERALIZEDTIME)
382296341Sdelphij        return ASN1_GENERALIZEDTIME_print(bp, tm);
383296341Sdelphij    BIO_write(bp, "Bad time value", 14);
384296341Sdelphij    return (0);
38555714Skris}
38655714Skris
387296341Sdelphijstatic const char *mon[12] = {
388296341Sdelphij    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
389296341Sdelphij    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
390296341Sdelphij};
39155714Skris
392238405Sjkimint ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
393296341Sdelphij{
394296341Sdelphij    char *v;
395296341Sdelphij    int gmt = 0;
396296341Sdelphij    int i;
397296341Sdelphij    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
398296341Sdelphij    char *f = NULL;
399296341Sdelphij    int f_len = 0;
40055714Skris
401296341Sdelphij    i = tm->length;
402296341Sdelphij    v = (char *)tm->data;
40355714Skris
404296341Sdelphij    if (i < 12)
405296341Sdelphij        goto err;
406296341Sdelphij    if (v[i - 1] == 'Z')
407296341Sdelphij        gmt = 1;
408296341Sdelphij    for (i = 0; i < 12; i++)
409296341Sdelphij        if ((v[i] > '9') || (v[i] < '0'))
410296341Sdelphij            goto err;
411296341Sdelphij    y = (v[0] - '0') * 1000 + (v[1] - '0') * 100
412296341Sdelphij        + (v[2] - '0') * 10 + (v[3] - '0');
413296341Sdelphij    M = (v[4] - '0') * 10 + (v[5] - '0');
414296341Sdelphij    if ((M > 12) || (M < 1))
415296341Sdelphij        goto err;
416296341Sdelphij    d = (v[6] - '0') * 10 + (v[7] - '0');
417296341Sdelphij    h = (v[8] - '0') * 10 + (v[9] - '0');
418296341Sdelphij    m = (v[10] - '0') * 10 + (v[11] - '0');
419296341Sdelphij    if (tm->length >= 14 &&
420296341Sdelphij        (v[12] >= '0') && (v[12] <= '9') &&
421296341Sdelphij        (v[13] >= '0') && (v[13] <= '9')) {
422296341Sdelphij        s = (v[12] - '0') * 10 + (v[13] - '0');
423296341Sdelphij        /* Check for fractions of seconds. */
424296341Sdelphij        if (tm->length >= 15 && v[14] == '.') {
425296341Sdelphij            int l = tm->length;
426296341Sdelphij            f = &v[14];         /* The decimal point. */
427296341Sdelphij            f_len = 1;
428296341Sdelphij            while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
429296341Sdelphij                ++f_len;
430296341Sdelphij        }
431296341Sdelphij    }
43255714Skris
433296341Sdelphij    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
434296341Sdelphij                   mon[M - 1], d, h, m, s, f_len, f, y,
435296341Sdelphij                   (gmt) ? " GMT" : "") <= 0)
436296341Sdelphij        return (0);
437296341Sdelphij    else
438296341Sdelphij        return (1);
439296341Sdelphij err:
440296341Sdelphij    BIO_write(bp, "Bad time value", 14);
441296341Sdelphij    return (0);
442296341Sdelphij}
44355714Skris
444238405Sjkimint ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
445296341Sdelphij{
446296341Sdelphij    const char *v;
447296341Sdelphij    int gmt = 0;
448296341Sdelphij    int i;
449296341Sdelphij    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
45055714Skris
451296341Sdelphij    i = tm->length;
452296341Sdelphij    v = (const char *)tm->data;
45355714Skris
454296341Sdelphij    if (i < 10)
455296341Sdelphij        goto err;
456296341Sdelphij    if (v[i - 1] == 'Z')
457296341Sdelphij        gmt = 1;
458296341Sdelphij    for (i = 0; i < 10; i++)
459296341Sdelphij        if ((v[i] > '9') || (v[i] < '0'))
460296341Sdelphij            goto err;
461296341Sdelphij    y = (v[0] - '0') * 10 + (v[1] - '0');
462296341Sdelphij    if (y < 50)
463296341Sdelphij        y += 100;
464296341Sdelphij    M = (v[2] - '0') * 10 + (v[3] - '0');
465296341Sdelphij    if ((M > 12) || (M < 1))
466296341Sdelphij        goto err;
467296341Sdelphij    d = (v[4] - '0') * 10 + (v[5] - '0');
468296341Sdelphij    h = (v[6] - '0') * 10 + (v[7] - '0');
469296341Sdelphij    m = (v[8] - '0') * 10 + (v[9] - '0');
470296341Sdelphij    if (tm->length >= 12 &&
471296341Sdelphij        (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
472296341Sdelphij        s = (v[10] - '0') * 10 + (v[11] - '0');
47355714Skris
474296341Sdelphij    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
475296341Sdelphij                   mon[M - 1], d, h, m, s, y + 1900,
476296341Sdelphij                   (gmt) ? " GMT" : "") <= 0)
477296341Sdelphij        return (0);
478296341Sdelphij    else
479296341Sdelphij        return (1);
480296341Sdelphij err:
481296341Sdelphij    BIO_write(bp, "Bad time value", 14);
482296341Sdelphij    return (0);
483296341Sdelphij}
48455714Skris
48555714Skrisint X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
486296341Sdelphij{
487296341Sdelphij    char *s, *c, *b;
488296341Sdelphij    int ret = 0, l, i;
48955714Skris
490296341Sdelphij    l = 80 - 2 - obase;
49155714Skris
492296341Sdelphij    b = X509_NAME_oneline(name, NULL, 0);
493296341Sdelphij    if (!b)
494296341Sdelphij        return 0;
495296341Sdelphij    if (!*b) {
496296341Sdelphij        OPENSSL_free(b);
497296341Sdelphij        return 1;
498296341Sdelphij    }
499296341Sdelphij    s = b + 1;                  /* skip the first slash */
50055714Skris
501296341Sdelphij    c = s;
502296341Sdelphij    for (;;) {
50355714Skris#ifndef CHARSET_EBCDIC
504296341Sdelphij        if (((*s == '/') &&
505296341Sdelphij             ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
506296341Sdelphij                                                 ((s[2] >= 'A')
507296341Sdelphij                                                  && (s[2] <= 'Z')
508296341Sdelphij                                                  && (s[3] == '='))
509296341Sdelphij              ))) || (*s == '\0'))
51055714Skris#else
511296341Sdelphij        if (((*s == '/') &&
512296341Sdelphij             (isupper(s[1]) && ((s[2] == '=') ||
513296341Sdelphij                                (isupper(s[2]) && (s[3] == '='))
514296341Sdelphij              ))) || (*s == '\0'))
51555714Skris#endif
516296341Sdelphij        {
517296341Sdelphij            i = s - c;
518296341Sdelphij            if (BIO_write(bp, c, i) != i)
519296341Sdelphij                goto err;
520296341Sdelphij            c = s + 1;          /* skip following slash */
521296341Sdelphij            if (*s != '\0') {
522296341Sdelphij                if (BIO_write(bp, ", ", 2) != 2)
523296341Sdelphij                    goto err;
524296341Sdelphij            }
525296341Sdelphij            l--;
526296341Sdelphij        }
527296341Sdelphij        if (*s == '\0')
528296341Sdelphij            break;
529296341Sdelphij        s++;
530296341Sdelphij        l--;
531296341Sdelphij    }
532296341Sdelphij
533296341Sdelphij    ret = 1;
534296341Sdelphij    if (0) {
535296341Sdelphij err:
536296341Sdelphij        X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
537296341Sdelphij    }
538296341Sdelphij    OPENSSL_free(b);
539296341Sdelphij    return (ret);
540296341Sdelphij}
541