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