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.
8296465Sdelphij *
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).
15296465Sdelphij *
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.
22296465Sdelphij *
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 :-).
37296465Sdelphij * 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)"
40296465Sdelphij *
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.
52296465Sdelphij *
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
64296465Sdelphij# include <openssl/rsa.h>
6555714Skris#endif
66109998Smarkm#ifndef OPENSSL_NO_DSA
67296465Sdelphij# include <openssl/dsa.h>
6855714Skris#endif
69160814Ssimon#ifndef OPENSSL_NO_EC
70296465Sdelphij# include <openssl/ec.h>
71160814Ssimon#endif
7255714Skris#include <openssl/objects.h>
7355714Skris#include <openssl/x509.h>
7455714Skris#include <openssl/x509v3.h>
7555714Skris
76109998Smarkm#ifndef OPENSSL_NO_FP_API
7755714Skrisint X509_print_fp(FILE *fp, X509 *x)
78296465Sdelphij{
79296465Sdelphij    return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
80296465Sdelphij}
81109998Smarkm
82296465Sdelphijint X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
83296465Sdelphij                     unsigned long cflag)
84296465Sdelphij{
85296465Sdelphij    BIO *b;
86296465Sdelphij    int ret;
8755714Skris
88296465Sdelphij    if ((b = BIO_new(BIO_s_file())) == NULL) {
89296465Sdelphij        X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
90296465Sdelphij        return (0);
91296465Sdelphij    }
92296465Sdelphij    BIO_set_fp(b, fp, BIO_NOCLOSE);
93296465Sdelphij    ret = X509_print_ex(b, x, nmflag, cflag);
94296465Sdelphij    BIO_free(b);
95296465Sdelphij    return (ret);
96296465Sdelphij}
9755714Skris#endif
9855714Skris
9955714Skrisint X509_print(BIO *bp, X509 *x)
100109998Smarkm{
101296465Sdelphij    return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
102109998Smarkm}
103109998Smarkm
104296465Sdelphijint X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
105296465Sdelphij                  unsigned long cflag)
106296465Sdelphij{
107296465Sdelphij    long l;
108296465Sdelphij    int ret = 0, i;
109296465Sdelphij    char *m = NULL, mlch = ' ';
110296465Sdelphij    int nmindent = 0;
111296465Sdelphij    X509_CINF *ci;
112296465Sdelphij    ASN1_INTEGER *bs;
113296465Sdelphij    EVP_PKEY *pkey = NULL;
114296465Sdelphij    const char *neg;
115296465Sdelphij    ASN1_STRING *str = NULL;
11655714Skris
117296465Sdelphij    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
118296465Sdelphij        mlch = '\n';
119296465Sdelphij        nmindent = 12;
120296465Sdelphij    }
121109998Smarkm
122296465Sdelphij    if (nmflags == X509_FLAG_COMPAT)
123296465Sdelphij        nmindent = 16;
124109998Smarkm
125296465Sdelphij    ci = x->cert_info;
126296465Sdelphij    if (!(cflag & X509_FLAG_NO_HEADER)) {
127296465Sdelphij        if (BIO_write(bp, "Certificate:\n", 13) <= 0)
128296465Sdelphij            goto err;
129296465Sdelphij        if (BIO_write(bp, "    Data:\n", 10) <= 0)
130296465Sdelphij            goto err;
131296465Sdelphij    }
132296465Sdelphij    if (!(cflag & X509_FLAG_NO_VERSION)) {
133296465Sdelphij        l = X509_get_version(x);
134296465Sdelphij        if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
135296465Sdelphij            goto err;
136296465Sdelphij    }
137296465Sdelphij    if (!(cflag & X509_FLAG_NO_SERIAL)) {
13855714Skris
139296465Sdelphij        if (BIO_write(bp, "        Serial Number:", 22) <= 0)
140296465Sdelphij            goto err;
141109998Smarkm
142296465Sdelphij        bs = X509_get_serialNumber(x);
143296465Sdelphij        if (bs->length <= 4) {
144296465Sdelphij            l = ASN1_INTEGER_get(bs);
145296465Sdelphij            if (l < 0) {
146296465Sdelphij                l = -l;
147296465Sdelphij                neg = "-";
148296465Sdelphij            } else
149296465Sdelphij                neg = "";
150296465Sdelphij            if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
151296465Sdelphij                goto err;
152296465Sdelphij        } else {
153296465Sdelphij            neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
154296465Sdelphij            if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
155296465Sdelphij                goto err;
15655714Skris
157296465Sdelphij            for (i = 0; i < bs->length; i++) {
158296465Sdelphij                if (BIO_printf(bp, "%02x%c", bs->data[i],
159296465Sdelphij                               ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
160296465Sdelphij                    goto err;
161296465Sdelphij            }
162296465Sdelphij        }
16355714Skris
164296465Sdelphij    }
16555714Skris
166296465Sdelphij    if (!(cflag & X509_FLAG_NO_SIGNAME)) {
167296465Sdelphij        if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0)
168296465Sdelphij            goto err;
169296465Sdelphij        if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
170296465Sdelphij            goto err;
171296465Sdelphij        if (BIO_puts(bp, "\n") <= 0)
172296465Sdelphij            goto err;
173296465Sdelphij    }
174109998Smarkm
175296465Sdelphij    if (!(cflag & X509_FLAG_NO_ISSUER)) {
176296465Sdelphij        if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
177296465Sdelphij            goto err;
178296465Sdelphij        if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
179296465Sdelphij            < 0)
180296465Sdelphij            goto err;
181296465Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
182296465Sdelphij            goto err;
183296465Sdelphij    }
184296465Sdelphij    if (!(cflag & X509_FLAG_NO_VALIDITY)) {
185296465Sdelphij        if (BIO_write(bp, "        Validity\n", 17) <= 0)
186296465Sdelphij            goto err;
187296465Sdelphij        if (BIO_write(bp, "            Not Before: ", 24) <= 0)
188296465Sdelphij            goto err;
189296465Sdelphij        if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
190296465Sdelphij            goto err;
191296465Sdelphij        if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
192296465Sdelphij            goto err;
193296465Sdelphij        if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
194296465Sdelphij            goto err;
195296465Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
196296465Sdelphij            goto err;
197296465Sdelphij    }
198296465Sdelphij    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
199296465Sdelphij        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
200296465Sdelphij            goto err;
201296465Sdelphij        if (X509_NAME_print_ex
202296465Sdelphij            (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
203296465Sdelphij            goto err;
204296465Sdelphij        if (BIO_write(bp, "\n", 1) <= 0)
205296465Sdelphij            goto err;
206296465Sdelphij    }
207296465Sdelphij    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
208296465Sdelphij        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
209296465Sdelphij            goto err;
210296465Sdelphij        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
211296465Sdelphij            goto err;
212296465Sdelphij        if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
213296465Sdelphij            goto err;
214296465Sdelphij        if (BIO_puts(bp, "\n") <= 0)
215296465Sdelphij            goto err;
21655714Skris
217296465Sdelphij        pkey = X509_get_pubkey(x);
218296465Sdelphij        if (pkey == NULL) {
219296465Sdelphij            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
220296465Sdelphij            ERR_print_errors(bp);
221296465Sdelphij        } else
222109998Smarkm#ifndef OPENSSL_NO_RSA
223296465Sdelphij        if (pkey->type == EVP_PKEY_RSA) {
224296465Sdelphij            BIO_printf(bp, "%12sRSA Public Key: (%d bit)\n", "",
225296465Sdelphij                       BN_num_bits(pkey->pkey.rsa->n));
226296465Sdelphij            RSA_print(bp, pkey->pkey.rsa, 16);
227296465Sdelphij        } else
228109998Smarkm#endif
229109998Smarkm#ifndef OPENSSL_NO_DSA
230296465Sdelphij        if (pkey->type == EVP_PKEY_DSA) {
231296465Sdelphij            BIO_printf(bp, "%12sDSA Public Key:\n", "");
232296465Sdelphij            DSA_print(bp, pkey->pkey.dsa, 16);
233296465Sdelphij        } else
234109998Smarkm#endif
235160814Ssimon#ifndef OPENSSL_NO_EC
236296465Sdelphij        if (pkey->type == EVP_PKEY_EC) {
237296465Sdelphij            BIO_printf(bp, "%12sEC Public Key:\n", "");
238296465Sdelphij            EC_KEY_print(bp, pkey->pkey.ec, 16);
239296465Sdelphij        } else
240160814Ssimon#endif
241296465Sdelphij            BIO_printf(bp, "%12sUnknown Public Key:\n", "");
242109998Smarkm
243296465Sdelphij        EVP_PKEY_free(pkey);
244296465Sdelphij    }
24555714Skris
246296465Sdelphij    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
247296465Sdelphij        X509V3_extensions_print(bp, "X509v3 extensions",
248296465Sdelphij                                ci->extensions, cflag, 8);
24955714Skris
250296465Sdelphij    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
251296465Sdelphij        if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
252296465Sdelphij            goto err;
253296465Sdelphij    }
254296465Sdelphij    if (!(cflag & X509_FLAG_NO_AUX)) {
255296465Sdelphij        if (!X509_CERT_AUX_print(bp, x->aux, 0))
256296465Sdelphij            goto err;
257296465Sdelphij    }
258296465Sdelphij    ret = 1;
259296465Sdelphij err:
260296465Sdelphij    if (str != NULL)
261296465Sdelphij        ASN1_STRING_free(str);
262296465Sdelphij    if (m != NULL)
263296465Sdelphij        OPENSSL_free(m);
264296465Sdelphij    return (ret);
265296465Sdelphij}
26655714Skris
267296465Sdelphijint X509_ocspid_print(BIO *bp, X509 *x)
268296465Sdelphij{
269296465Sdelphij    unsigned char *der = NULL;
270296465Sdelphij    unsigned char *dertmp;
271296465Sdelphij    int derlen;
272296465Sdelphij    int i;
273296465Sdelphij    unsigned char SHA1md[SHA_DIGEST_LENGTH];
274109998Smarkm
275296465Sdelphij    /*
276296465Sdelphij     * display the hash of the subject as it would appear in OCSP requests
277296465Sdelphij     */
278296465Sdelphij    if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
279296465Sdelphij        goto err;
280296465Sdelphij    derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
281296465Sdelphij    if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL)
282296465Sdelphij        goto err;
283296465Sdelphij    i2d_X509_NAME(x->cert_info->subject, &dertmp);
284109998Smarkm
285296465Sdelphij    EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL);
286296465Sdelphij    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
287296465Sdelphij        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
288296465Sdelphij            goto err;
289296465Sdelphij    }
290296465Sdelphij    OPENSSL_free(der);
291296465Sdelphij    der = NULL;
292109998Smarkm
293296465Sdelphij    /*
294296465Sdelphij     * display the hash of the public key as it would appear in OCSP requests
295296465Sdelphij     */
296296465Sdelphij    if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
297296465Sdelphij        goto err;
298109998Smarkm
299296465Sdelphij    EVP_Digest(x->cert_info->key->public_key->data,
300296465Sdelphij               x->cert_info->key->public_key->length, SHA1md, NULL,
301296465Sdelphij               EVP_sha1(), NULL);
302296465Sdelphij    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
303296465Sdelphij        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
304296465Sdelphij            goto err;
305296465Sdelphij    }
306296465Sdelphij    BIO_printf(bp, "\n");
307109998Smarkm
308296465Sdelphij    return (1);
309296465Sdelphij err:
310296465Sdelphij    if (der != NULL)
311296465Sdelphij        OPENSSL_free(der);
312296465Sdelphij    return (0);
313296465Sdelphij}
314109998Smarkm
315109998Smarkmint X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
316109998Smarkm{
317296465Sdelphij    unsigned char *s;
318296465Sdelphij    int i, n;
319296465Sdelphij    if (BIO_puts(bp, "    Signature Algorithm: ") <= 0)
320296465Sdelphij        return 0;
321296465Sdelphij    if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
322296465Sdelphij        return 0;
323109998Smarkm
324296465Sdelphij    n = sig->length;
325296465Sdelphij    s = sig->data;
326296465Sdelphij    for (i = 0; i < n; i++) {
327296465Sdelphij        if ((i % 18) == 0)
328296465Sdelphij            if (BIO_write(bp, "\n        ", 9) <= 0)
329296465Sdelphij                return 0;
330296465Sdelphij        if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
331296465Sdelphij            return 0;
332296465Sdelphij    }
333296465Sdelphij    if (BIO_write(bp, "\n", 1) != 1)
334296465Sdelphij        return 0;
335296465Sdelphij    return 1;
336109998Smarkm}
337109998Smarkm
33855714Skrisint ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
339296465Sdelphij{
340296465Sdelphij    int i, n;
341296465Sdelphij    char buf[80], *p;
34255714Skris
343296465Sdelphij    if (v == NULL)
344296465Sdelphij        return (0);
345296465Sdelphij    n = 0;
346296465Sdelphij    p = (char *)v->data;
347296465Sdelphij    for (i = 0; i < v->length; i++) {
348296465Sdelphij        if ((p[i] > '~') || ((p[i] < ' ') &&
349296465Sdelphij                             (p[i] != '\n') && (p[i] != '\r')))
350296465Sdelphij            buf[n] = '.';
351296465Sdelphij        else
352296465Sdelphij            buf[n] = p[i];
353296465Sdelphij        n++;
354296465Sdelphij        if (n >= 80) {
355296465Sdelphij            if (BIO_write(bp, buf, n) <= 0)
356296465Sdelphij                return (0);
357296465Sdelphij            n = 0;
358296465Sdelphij        }
359296465Sdelphij    }
360296465Sdelphij    if (n > 0)
361296465Sdelphij        if (BIO_write(bp, buf, n) <= 0)
362296465Sdelphij            return (0);
363296465Sdelphij    return (1);
364296465Sdelphij}
36555714Skris
36655714Skrisint ASN1_TIME_print(BIO *bp, ASN1_TIME *tm)
36755714Skris{
368296465Sdelphij    if (tm->type == V_ASN1_UTCTIME)
369296465Sdelphij        return ASN1_UTCTIME_print(bp, tm);
370296465Sdelphij    if (tm->type == V_ASN1_GENERALIZEDTIME)
371296465Sdelphij        return ASN1_GENERALIZEDTIME_print(bp, tm);
372296465Sdelphij    BIO_write(bp, "Bad time value", 14);
373296465Sdelphij    return (0);
37455714Skris}
37555714Skris
376296465Sdelphijstatic const char *mon[12] = {
377296465Sdelphij    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
378296465Sdelphij    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
379296465Sdelphij};
38055714Skris
38155714Skrisint ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
382296465Sdelphij{
383296465Sdelphij    char *v;
384296465Sdelphij    int gmt = 0;
385296465Sdelphij    int i;
386296465Sdelphij    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
387296465Sdelphij    char *f = NULL;
388296465Sdelphij    int f_len = 0;
38955714Skris
390296465Sdelphij    i = tm->length;
391296465Sdelphij    v = (char *)tm->data;
39255714Skris
393296465Sdelphij    if (i < 12)
394296465Sdelphij        goto err;
395296465Sdelphij    if (v[i - 1] == 'Z')
396296465Sdelphij        gmt = 1;
397296465Sdelphij    for (i = 0; i < 12; i++)
398296465Sdelphij        if ((v[i] > '9') || (v[i] < '0'))
399296465Sdelphij            goto err;
400296465Sdelphij    y = (v[0] - '0') * 1000 + (v[1] - '0') * 100
401296465Sdelphij        + (v[2] - '0') * 10 + (v[3] - '0');
402296465Sdelphij    M = (v[4] - '0') * 10 + (v[5] - '0');
403296465Sdelphij    if ((M > 12) || (M < 1))
404296465Sdelphij        goto err;
405296465Sdelphij    d = (v[6] - '0') * 10 + (v[7] - '0');
406296465Sdelphij    h = (v[8] - '0') * 10 + (v[9] - '0');
407296465Sdelphij    m = (v[10] - '0') * 10 + (v[11] - '0');
408296465Sdelphij    if (tm->length >= 14 &&
409296465Sdelphij        (v[12] >= '0') && (v[12] <= '9') &&
410296465Sdelphij        (v[13] >= '0') && (v[13] <= '9')) {
411296465Sdelphij        s = (v[12] - '0') * 10 + (v[13] - '0');
412296465Sdelphij        /* Check for fractions of seconds. */
413296465Sdelphij        if (tm->length >= 15 && v[14] == '.') {
414296465Sdelphij            int l = tm->length;
415296465Sdelphij            f = &v[14];         /* The decimal point. */
416296465Sdelphij            f_len = 1;
417296465Sdelphij            while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
418296465Sdelphij                ++f_len;
419296465Sdelphij        }
420296465Sdelphij    }
42155714Skris
422296465Sdelphij    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
423296465Sdelphij                   mon[M - 1], d, h, m, s, f_len, f, y,
424296465Sdelphij                   (gmt) ? " GMT" : "") <= 0)
425296465Sdelphij        return (0);
426296465Sdelphij    else
427296465Sdelphij        return (1);
428296465Sdelphij err:
429296465Sdelphij    BIO_write(bp, "Bad time value", 14);
430296465Sdelphij    return (0);
431296465Sdelphij}
43255714Skris
43355714Skrisint ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm)
434296465Sdelphij{
435296465Sdelphij    char *v;
436296465Sdelphij    int gmt = 0;
437296465Sdelphij    int i;
438296465Sdelphij    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
43955714Skris
440296465Sdelphij    i = tm->length;
441296465Sdelphij    v = (char *)tm->data;
44255714Skris
443296465Sdelphij    if (i < 10)
444296465Sdelphij        goto err;
445296465Sdelphij    if (v[i - 1] == 'Z')
446296465Sdelphij        gmt = 1;
447296465Sdelphij    for (i = 0; i < 10; i++)
448296465Sdelphij        if ((v[i] > '9') || (v[i] < '0'))
449296465Sdelphij            goto err;
450296465Sdelphij    y = (v[0] - '0') * 10 + (v[1] - '0');
451296465Sdelphij    if (y < 50)
452296465Sdelphij        y += 100;
453296465Sdelphij    M = (v[2] - '0') * 10 + (v[3] - '0');
454296465Sdelphij    if ((M > 12) || (M < 1))
455296465Sdelphij        goto err;
456296465Sdelphij    d = (v[4] - '0') * 10 + (v[5] - '0');
457296465Sdelphij    h = (v[6] - '0') * 10 + (v[7] - '0');
458296465Sdelphij    m = (v[8] - '0') * 10 + (v[9] - '0');
459296465Sdelphij    if (tm->length >= 12 &&
460296465Sdelphij        (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
461296465Sdelphij        s = (v[10] - '0') * 10 + (v[11] - '0');
46255714Skris
463296465Sdelphij    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
464296465Sdelphij                   mon[M - 1], d, h, m, s, y + 1900,
465296465Sdelphij                   (gmt) ? " GMT" : "") <= 0)
466296465Sdelphij        return (0);
467296465Sdelphij    else
468296465Sdelphij        return (1);
469296465Sdelphij err:
470296465Sdelphij    BIO_write(bp, "Bad time value", 14);
471296465Sdelphij    return (0);
472296465Sdelphij}
47355714Skris
47455714Skrisint X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
475296465Sdelphij{
476296465Sdelphij    char *s, *c, *b;
477296465Sdelphij    int ret = 0, l, i;
47855714Skris
479296465Sdelphij    l = 80 - 2 - obase;
48055714Skris
481296465Sdelphij    b = X509_NAME_oneline(name, NULL, 0);
482296465Sdelphij    if (!b)
483296465Sdelphij        return 0;
484296465Sdelphij    if (!*b) {
485296465Sdelphij        OPENSSL_free(b);
486296465Sdelphij        return 1;
487296465Sdelphij    }
488296465Sdelphij    s = b + 1;                  /* skip the first slash */
48955714Skris
490296465Sdelphij    c = s;
491296465Sdelphij    for (;;) {
49255714Skris#ifndef CHARSET_EBCDIC
493296465Sdelphij        if (((*s == '/') &&
494296465Sdelphij             ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
495296465Sdelphij                                                 ((s[2] >= 'A')
496296465Sdelphij                                                  && (s[2] <= 'Z')
497296465Sdelphij                                                  && (s[3] == '='))
498296465Sdelphij              ))) || (*s == '\0'))
49955714Skris#else
500296465Sdelphij        if (((*s == '/') &&
501296465Sdelphij             (isupper(s[1]) && ((s[2] == '=') ||
502296465Sdelphij                                (isupper(s[2]) && (s[3] == '='))
503296465Sdelphij              ))) || (*s == '\0'))
50455714Skris#endif
505296465Sdelphij        {
506296465Sdelphij            i = s - c;
507296465Sdelphij            if (BIO_write(bp, c, i) != i)
508296465Sdelphij                goto err;
509296465Sdelphij            c = s + 1;          /* skip following slash */
510296465Sdelphij            if (*s != '\0') {
511296465Sdelphij                if (BIO_write(bp, ", ", 2) != 2)
512296465Sdelphij                    goto err;
513296465Sdelphij            }
514296465Sdelphij            l--;
515296465Sdelphij        }
516296465Sdelphij        if (*s == '\0')
517296465Sdelphij            break;
518296465Sdelphij        s++;
519296465Sdelphij        l--;
520296465Sdelphij    }
521296465Sdelphij
522296465Sdelphij    ret = 1;
523296465Sdelphij    if (0) {
524296465Sdelphij err:
525296465Sdelphij        X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
526296465Sdelphij    }
527296465Sdelphij    OPENSSL_free(b);
528296465Sdelphij    return (ret);
529296465Sdelphij}
530