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. 8280297Sjkim * 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). 15280297Sjkim * 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. 22280297Sjkim * 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 :-). 37280297Sjkim * 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)" 40280297Sjkim * 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. 52280297Sjkim * 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 64280297Sjkim# include <openssl/rsa.h> 6555714Skris#endif 66109998Smarkm#ifndef OPENSSL_NO_DSA 67280297Sjkim# include <openssl/dsa.h> 6855714Skris#endif 69160814Ssimon#ifndef OPENSSL_NO_EC 70280297Sjkim# 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) 79280297Sjkim{ 80280297Sjkim return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); 81280297Sjkim} 82109998Smarkm 83280297Sjkimint X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, 84280297Sjkim unsigned long cflag) 85280297Sjkim{ 86280297Sjkim BIO *b; 87280297Sjkim int ret; 8855714Skris 89280297Sjkim if ((b = BIO_new(BIO_s_file())) == NULL) { 90280297Sjkim X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB); 91280297Sjkim return (0); 92280297Sjkim } 93280297Sjkim BIO_set_fp(b, fp, BIO_NOCLOSE); 94280297Sjkim ret = X509_print_ex(b, x, nmflag, cflag); 95280297Sjkim BIO_free(b); 96280297Sjkim return (ret); 97280297Sjkim} 9855714Skris#endif 9955714Skris 10055714Skrisint X509_print(BIO *bp, X509 *x) 101109998Smarkm{ 102280297Sjkim return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); 103109998Smarkm} 104109998Smarkm 105280297Sjkimint X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, 106280297Sjkim unsigned long cflag) 107280297Sjkim{ 108280297Sjkim long l; 109280297Sjkim int ret = 0, i; 110280297Sjkim char *m = NULL, mlch = ' '; 111280297Sjkim int nmindent = 0; 112280297Sjkim X509_CINF *ci; 113280297Sjkim ASN1_INTEGER *bs; 114280297Sjkim EVP_PKEY *pkey = NULL; 115280297Sjkim const char *neg; 11655714Skris 117280297Sjkim if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 118280297Sjkim mlch = '\n'; 119280297Sjkim nmindent = 12; 120280297Sjkim } 121109998Smarkm 122280297Sjkim if (nmflags == X509_FLAG_COMPAT) 123280297Sjkim nmindent = 16; 124109998Smarkm 125280297Sjkim ci = x->cert_info; 126280297Sjkim if (!(cflag & X509_FLAG_NO_HEADER)) { 127280297Sjkim if (BIO_write(bp, "Certificate:\n", 13) <= 0) 128280297Sjkim goto err; 129280297Sjkim if (BIO_write(bp, " Data:\n", 10) <= 0) 130280297Sjkim goto err; 131280297Sjkim } 132280297Sjkim if (!(cflag & X509_FLAG_NO_VERSION)) { 133280297Sjkim l = X509_get_version(x); 134280297Sjkim if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0) 135280297Sjkim goto err; 136280297Sjkim } 137280297Sjkim if (!(cflag & X509_FLAG_NO_SERIAL)) { 13855714Skris 139280297Sjkim if (BIO_write(bp, " Serial Number:", 22) <= 0) 140280297Sjkim goto err; 141109998Smarkm 142280297Sjkim bs = X509_get_serialNumber(x); 143298998Sjkim if (bs->length < (int)sizeof(long) 144298998Sjkim || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) { 145280297Sjkim l = ASN1_INTEGER_get(bs); 146280297Sjkim if (bs->type == V_ASN1_NEG_INTEGER) { 147280297Sjkim l = -l; 148280297Sjkim neg = "-"; 149280297Sjkim } else 150280297Sjkim neg = ""; 151280297Sjkim if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0) 152280297Sjkim goto err; 153280297Sjkim } else { 154280297Sjkim neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; 155280297Sjkim if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) 156280297Sjkim goto err; 15755714Skris 158280297Sjkim for (i = 0; i < bs->length; i++) { 159280297Sjkim if (BIO_printf(bp, "%02x%c", bs->data[i], 160280297Sjkim ((i + 1 == bs->length) ? '\n' : ':')) <= 0) 161280297Sjkim goto err; 162280297Sjkim } 163280297Sjkim } 16455714Skris 165280297Sjkim } 16655714Skris 167280297Sjkim if (!(cflag & X509_FLAG_NO_SIGNAME)) { 168280297Sjkim if (X509_signature_print(bp, ci->signature, NULL) <= 0) 169280297Sjkim goto err; 170238405Sjkim#if 0 171280297Sjkim if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0) 172280297Sjkim goto err; 173280297Sjkim if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0) 174280297Sjkim goto err; 175280297Sjkim if (BIO_puts(bp, "\n") <= 0) 176280297Sjkim goto err; 177238405Sjkim#endif 178280297Sjkim } 179109998Smarkm 180280297Sjkim if (!(cflag & X509_FLAG_NO_ISSUER)) { 181280297Sjkim if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) 182280297Sjkim goto err; 183280297Sjkim if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) 184280297Sjkim < 0) 185280297Sjkim goto err; 186280297Sjkim if (BIO_write(bp, "\n", 1) <= 0) 187280297Sjkim goto err; 188280297Sjkim } 189280297Sjkim if (!(cflag & X509_FLAG_NO_VALIDITY)) { 190280297Sjkim if (BIO_write(bp, " Validity\n", 17) <= 0) 191280297Sjkim goto err; 192280297Sjkim if (BIO_write(bp, " Not Before: ", 24) <= 0) 193280297Sjkim goto err; 194280297Sjkim if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) 195280297Sjkim goto err; 196280297Sjkim if (BIO_write(bp, "\n Not After : ", 25) <= 0) 197280297Sjkim goto err; 198280297Sjkim if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) 199280297Sjkim goto err; 200280297Sjkim if (BIO_write(bp, "\n", 1) <= 0) 201280297Sjkim goto err; 202280297Sjkim } 203280297Sjkim if (!(cflag & X509_FLAG_NO_SUBJECT)) { 204280297Sjkim if (BIO_printf(bp, " Subject:%c", mlch) <= 0) 205280297Sjkim goto err; 206280297Sjkim if (X509_NAME_print_ex 207280297Sjkim (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) 208280297Sjkim goto err; 209280297Sjkim if (BIO_write(bp, "\n", 1) <= 0) 210280297Sjkim goto err; 211280297Sjkim } 212280297Sjkim if (!(cflag & X509_FLAG_NO_PUBKEY)) { 213280297Sjkim if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) 214280297Sjkim goto err; 215280297Sjkim if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) 216280297Sjkim goto err; 217280297Sjkim if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) 218280297Sjkim goto err; 219280297Sjkim if (BIO_puts(bp, "\n") <= 0) 220280297Sjkim goto err; 22155714Skris 222280297Sjkim pkey = X509_get_pubkey(x); 223280297Sjkim if (pkey == NULL) { 224280297Sjkim BIO_printf(bp, "%12sUnable to load Public Key\n", ""); 225280297Sjkim ERR_print_errors(bp); 226280297Sjkim } else { 227280297Sjkim EVP_PKEY_print_public(bp, pkey, 16, NULL); 228280297Sjkim EVP_PKEY_free(pkey); 229280297Sjkim } 230280297Sjkim } 23155714Skris 232290207Sjkim if (!(cflag & X509_FLAG_NO_IDS)) { 233290207Sjkim if (ci->issuerUID) { 234290207Sjkim if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) 235290207Sjkim goto err; 236290207Sjkim if (!X509_signature_dump(bp, ci->issuerUID, 12)) 237290207Sjkim goto err; 238290207Sjkim } 239290207Sjkim if (ci->subjectUID) { 240290207Sjkim if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) 241290207Sjkim goto err; 242290207Sjkim if (!X509_signature_dump(bp, ci->subjectUID, 12)) 243290207Sjkim goto err; 244290207Sjkim } 245290207Sjkim } 246290207Sjkim 247280297Sjkim if (!(cflag & X509_FLAG_NO_EXTENSIONS)) 248280297Sjkim X509V3_extensions_print(bp, "X509v3 extensions", 249280297Sjkim ci->extensions, cflag, 8); 25055714Skris 251280297Sjkim if (!(cflag & X509_FLAG_NO_SIGDUMP)) { 252280297Sjkim if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) 253280297Sjkim goto err; 254280297Sjkim } 255280297Sjkim if (!(cflag & X509_FLAG_NO_AUX)) { 256280297Sjkim if (!X509_CERT_AUX_print(bp, x->aux, 0)) 257280297Sjkim goto err; 258280297Sjkim } 259280297Sjkim ret = 1; 260280297Sjkim err: 261280297Sjkim if (m != NULL) 262280297Sjkim OPENSSL_free(m); 263280297Sjkim return (ret); 264280297Sjkim} 26555714Skris 266280297Sjkimint X509_ocspid_print(BIO *bp, X509 *x) 267280297Sjkim{ 268280297Sjkim unsigned char *der = NULL; 269280297Sjkim unsigned char *dertmp; 270280297Sjkim int derlen; 271280297Sjkim int i; 272280297Sjkim unsigned char SHA1md[SHA_DIGEST_LENGTH]; 273109998Smarkm 274280297Sjkim /* 275280297Sjkim * display the hash of the subject as it would appear in OCSP requests 276280297Sjkim */ 277280297Sjkim if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) 278280297Sjkim goto err; 279280297Sjkim derlen = i2d_X509_NAME(x->cert_info->subject, NULL); 280280297Sjkim if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL) 281280297Sjkim goto err; 282280297Sjkim i2d_X509_NAME(x->cert_info->subject, &dertmp); 283109998Smarkm 284280297Sjkim if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) 285280297Sjkim goto err; 286280297Sjkim for (i = 0; i < SHA_DIGEST_LENGTH; i++) { 287280297Sjkim if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) 288280297Sjkim goto err; 289280297Sjkim } 290280297Sjkim OPENSSL_free(der); 291280297Sjkim der = NULL; 292109998Smarkm 293280297Sjkim /* 294280297Sjkim * display the hash of the public key as it would appear in OCSP requests 295280297Sjkim */ 296280297Sjkim if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) 297280297Sjkim goto err; 298109998Smarkm 299280297Sjkim if (!EVP_Digest(x->cert_info->key->public_key->data, 300280297Sjkim x->cert_info->key->public_key->length, 301280297Sjkim SHA1md, NULL, EVP_sha1(), NULL)) 302280297Sjkim goto err; 303280297Sjkim for (i = 0; i < SHA_DIGEST_LENGTH; i++) { 304280297Sjkim if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) 305280297Sjkim goto err; 306280297Sjkim } 307280297Sjkim BIO_printf(bp, "\n"); 308109998Smarkm 309280297Sjkim return (1); 310280297Sjkim err: 311280297Sjkim if (der != NULL) 312280297Sjkim OPENSSL_free(der); 313280297Sjkim return (0); 314280297Sjkim} 315109998Smarkm 316238405Sjkimint X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) 317109998Smarkm{ 318280297Sjkim const unsigned char *s; 319280297Sjkim int i, n; 320109998Smarkm 321280297Sjkim n = sig->length; 322280297Sjkim s = sig->data; 323280297Sjkim for (i = 0; i < n; i++) { 324280297Sjkim if ((i % 18) == 0) { 325280297Sjkim if (BIO_write(bp, "\n", 1) <= 0) 326280297Sjkim return 0; 327280297Sjkim if (BIO_indent(bp, indent, indent) <= 0) 328280297Sjkim return 0; 329280297Sjkim } 330280297Sjkim if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0) 331280297Sjkim return 0; 332280297Sjkim } 333280297Sjkim if (BIO_write(bp, "\n", 1) != 1) 334280297Sjkim return 0; 335238405Sjkim 336280297Sjkim return 1; 337109998Smarkm} 338109998Smarkm 339238405Sjkimint X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig) 340238405Sjkim{ 341280297Sjkim int sig_nid; 342280297Sjkim if (BIO_puts(bp, " Signature Algorithm: ") <= 0) 343280297Sjkim return 0; 344280297Sjkim if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) 345280297Sjkim return 0; 346238405Sjkim 347280297Sjkim sig_nid = OBJ_obj2nid(sigalg->algorithm); 348280297Sjkim if (sig_nid != NID_undef) { 349280297Sjkim int pkey_nid, dig_nid; 350280297Sjkim const EVP_PKEY_ASN1_METHOD *ameth; 351280297Sjkim if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { 352280297Sjkim ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); 353280297Sjkim if (ameth && ameth->sig_print) 354280297Sjkim return ameth->sig_print(bp, sigalg, sig, 9, 0); 355280297Sjkim } 356280297Sjkim } 357280297Sjkim if (sig) 358280297Sjkim return X509_signature_dump(bp, sig, 9); 359280297Sjkim else if (BIO_puts(bp, "\n") <= 0) 360280297Sjkim return 0; 361280297Sjkim return 1; 362238405Sjkim} 363238405Sjkim 364238405Sjkimint ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) 365280297Sjkim{ 366280297Sjkim int i, n; 367280297Sjkim char buf[80]; 368280297Sjkim const char *p; 36955714Skris 370280297Sjkim if (v == NULL) 371280297Sjkim return (0); 372280297Sjkim n = 0; 373280297Sjkim p = (const char *)v->data; 374280297Sjkim for (i = 0; i < v->length; i++) { 375280297Sjkim if ((p[i] > '~') || ((p[i] < ' ') && 376280297Sjkim (p[i] != '\n') && (p[i] != '\r'))) 377280297Sjkim buf[n] = '.'; 378280297Sjkim else 379280297Sjkim buf[n] = p[i]; 380280297Sjkim n++; 381280297Sjkim if (n >= 80) { 382280297Sjkim if (BIO_write(bp, buf, n) <= 0) 383280297Sjkim return (0); 384280297Sjkim n = 0; 385280297Sjkim } 386280297Sjkim } 387280297Sjkim if (n > 0) 388280297Sjkim if (BIO_write(bp, buf, n) <= 0) 389280297Sjkim return (0); 390280297Sjkim return (1); 391280297Sjkim} 39255714Skris 393238405Sjkimint ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) 39455714Skris{ 395280297Sjkim if (tm->type == V_ASN1_UTCTIME) 396280297Sjkim return ASN1_UTCTIME_print(bp, tm); 397280297Sjkim if (tm->type == V_ASN1_GENERALIZEDTIME) 398280297Sjkim return ASN1_GENERALIZEDTIME_print(bp, tm); 399280297Sjkim BIO_write(bp, "Bad time value", 14); 400280297Sjkim return (0); 40155714Skris} 40255714Skris 403280297Sjkimstatic const char *mon[12] = { 404280297Sjkim "Jan", "Feb", "Mar", "Apr", "May", "Jun", 405280297Sjkim "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 406280297Sjkim}; 40755714Skris 408238405Sjkimint ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) 409280297Sjkim{ 410280297Sjkim char *v; 411280297Sjkim int gmt = 0; 412280297Sjkim int i; 413280297Sjkim int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; 414280297Sjkim char *f = NULL; 415280297Sjkim int f_len = 0; 41655714Skris 417280297Sjkim i = tm->length; 418280297Sjkim v = (char *)tm->data; 41955714Skris 420280297Sjkim if (i < 12) 421280297Sjkim goto err; 422280297Sjkim if (v[i - 1] == 'Z') 423280297Sjkim gmt = 1; 424280297Sjkim for (i = 0; i < 12; i++) 425280297Sjkim if ((v[i] > '9') || (v[i] < '0')) 426280297Sjkim goto err; 427280297Sjkim y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 428280297Sjkim + (v[2] - '0') * 10 + (v[3] - '0'); 429280297Sjkim M = (v[4] - '0') * 10 + (v[5] - '0'); 430280297Sjkim if ((M > 12) || (M < 1)) 431280297Sjkim goto err; 432280297Sjkim d = (v[6] - '0') * 10 + (v[7] - '0'); 433280297Sjkim h = (v[8] - '0') * 10 + (v[9] - '0'); 434280297Sjkim m = (v[10] - '0') * 10 + (v[11] - '0'); 435280297Sjkim if (tm->length >= 14 && 436280297Sjkim (v[12] >= '0') && (v[12] <= '9') && 437280297Sjkim (v[13] >= '0') && (v[13] <= '9')) { 438280297Sjkim s = (v[12] - '0') * 10 + (v[13] - '0'); 439280297Sjkim /* Check for fractions of seconds. */ 440280297Sjkim if (tm->length >= 15 && v[14] == '.') { 441280297Sjkim int l = tm->length; 442280297Sjkim f = &v[14]; /* The decimal point. */ 443280297Sjkim f_len = 1; 444280297Sjkim while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9') 445280297Sjkim ++f_len; 446280297Sjkim } 447280297Sjkim } 44855714Skris 449280297Sjkim if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", 450280297Sjkim mon[M - 1], d, h, m, s, f_len, f, y, 451280297Sjkim (gmt) ? " GMT" : "") <= 0) 452280297Sjkim return (0); 453280297Sjkim else 454280297Sjkim return (1); 455280297Sjkim err: 456280297Sjkim BIO_write(bp, "Bad time value", 14); 457280297Sjkim return (0); 458280297Sjkim} 45955714Skris 460238405Sjkimint ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) 461280297Sjkim{ 462280297Sjkim const char *v; 463280297Sjkim int gmt = 0; 464280297Sjkim int i; 465280297Sjkim int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; 46655714Skris 467280297Sjkim i = tm->length; 468280297Sjkim v = (const char *)tm->data; 46955714Skris 470280297Sjkim if (i < 10) 471280297Sjkim goto err; 472280297Sjkim if (v[i - 1] == 'Z') 473280297Sjkim gmt = 1; 474280297Sjkim for (i = 0; i < 10; i++) 475280297Sjkim if ((v[i] > '9') || (v[i] < '0')) 476280297Sjkim goto err; 477280297Sjkim y = (v[0] - '0') * 10 + (v[1] - '0'); 478280297Sjkim if (y < 50) 479280297Sjkim y += 100; 480280297Sjkim M = (v[2] - '0') * 10 + (v[3] - '0'); 481280297Sjkim if ((M > 12) || (M < 1)) 482280297Sjkim goto err; 483280297Sjkim d = (v[4] - '0') * 10 + (v[5] - '0'); 484280297Sjkim h = (v[6] - '0') * 10 + (v[7] - '0'); 485280297Sjkim m = (v[8] - '0') * 10 + (v[9] - '0'); 486280297Sjkim if (tm->length >= 12 && 487280297Sjkim (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) 488280297Sjkim s = (v[10] - '0') * 10 + (v[11] - '0'); 48955714Skris 490280297Sjkim if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", 491280297Sjkim mon[M - 1], d, h, m, s, y + 1900, 492280297Sjkim (gmt) ? " GMT" : "") <= 0) 493280297Sjkim return (0); 494280297Sjkim else 495280297Sjkim return (1); 496280297Sjkim err: 497280297Sjkim BIO_write(bp, "Bad time value", 14); 498280297Sjkim return (0); 499280297Sjkim} 50055714Skris 50155714Skrisint X509_NAME_print(BIO *bp, X509_NAME *name, int obase) 502280297Sjkim{ 503280297Sjkim char *s, *c, *b; 504280297Sjkim int ret = 0, l, i; 50555714Skris 506280297Sjkim l = 80 - 2 - obase; 50755714Skris 508280297Sjkim b = X509_NAME_oneline(name, NULL, 0); 509280297Sjkim if (!b) 510280297Sjkim return 0; 511280297Sjkim if (!*b) { 512280297Sjkim OPENSSL_free(b); 513280297Sjkim return 1; 514280297Sjkim } 515280297Sjkim s = b + 1; /* skip the first slash */ 51655714Skris 517280297Sjkim c = s; 518280297Sjkim for (;;) { 51955714Skris#ifndef CHARSET_EBCDIC 520280297Sjkim if (((*s == '/') && 521280297Sjkim ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || 522280297Sjkim ((s[2] >= 'A') 523280297Sjkim && (s[2] <= 'Z') 524280297Sjkim && (s[3] == '=')) 525280297Sjkim ))) || (*s == '\0')) 52655714Skris#else 527280297Sjkim if (((*s == '/') && 528280297Sjkim (isupper(s[1]) && ((s[2] == '=') || 529280297Sjkim (isupper(s[2]) && (s[3] == '=')) 530280297Sjkim ))) || (*s == '\0')) 53155714Skris#endif 532280297Sjkim { 533280297Sjkim i = s - c; 534280297Sjkim if (BIO_write(bp, c, i) != i) 535280297Sjkim goto err; 536280297Sjkim c = s + 1; /* skip following slash */ 537280297Sjkim if (*s != '\0') { 538280297Sjkim if (BIO_write(bp, ", ", 2) != 2) 539280297Sjkim goto err; 540280297Sjkim } 541280297Sjkim l--; 542280297Sjkim } 543280297Sjkim if (*s == '\0') 544280297Sjkim break; 545280297Sjkim s++; 546280297Sjkim l--; 547280297Sjkim } 548280297Sjkim 549280297Sjkim ret = 1; 550280297Sjkim if (0) { 551280297Sjkim err: 552280297Sjkim X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB); 553280297Sjkim } 554280297Sjkim OPENSSL_free(b); 555280297Sjkim return (ret); 556280297Sjkim} 557