Home | History | Annotate | Download | only in asn1
      1 /* crypto/asn1/t_x509.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) cryptsoft.com).
      7  * The implementation was written so as to conform with Netscapes SSL.
      8  *
      9  * This library is free for commercial and non-commercial use as long as
     10  * the following conditions are aheared to.  The following conditions
     11  * apply to all code found in this distribution, be it the RC4, RSA,
     12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     13  * included with this distribution is covered by the same copyright terms
     14  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     15  *
     16  * Copyright remains Eric Young's, and as such any Copyright notices in
     17  * the code are not to be removed.
     18  * If this package is used in a product, Eric Young should be given attribution
     19  * as the author of the parts of the library used.
     20  * This can be in the form of a textual message at program startup or
     21  * in documentation (online or textual) provided with the package.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  * 3. All advertising materials mentioning features or use of this software
     32  *    must display the following acknowledgement:
     33  *    "This product includes cryptographic software written by
     34  *     Eric Young (eay (at) cryptsoft.com)"
     35  *    The word 'cryptographic' can be left out if the rouines from the library
     36  *    being used are not cryptographic related :-).
     37  * 4. If you include any Windows specific code (or a derivative thereof) from
     38  *    the apps directory (application code) you must include an acknowledgement:
     39  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  *
     53  * The licence and distribution terms for any publically available version or
     54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     55  * copied and put under another distribution licence
     56  * [including the GNU Public Licence.]
     57  */
     58 
     59 #include <stdio.h>
     60 #include "cryptlib.h"
     61 #include <openssl/buffer.h>
     62 #include <openssl/bn.h>
     63 #ifndef OPENSSL_NO_RSA
     64 #include <openssl/rsa.h>
     65 #endif
     66 #ifndef OPENSSL_NO_DSA
     67 #include <openssl/dsa.h>
     68 #endif
     69 #ifndef OPENSSL_NO_EC
     70 #include <openssl/ec.h>
     71 #endif
     72 #include <openssl/objects.h>
     73 #include <openssl/x509.h>
     74 #include <openssl/x509v3.h>
     75 
     76 #ifndef OPENSSL_NO_FP_API
     77 int X509_print_fp(FILE *fp, X509 *x)
     78 	{
     79 	return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
     80 	}
     81 
     82 int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
     83         {
     84         BIO *b;
     85         int ret;
     86 
     87         if ((b=BIO_new(BIO_s_file())) == NULL)
     88 		{
     89 		X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB);
     90                 return(0);
     91 		}
     92         BIO_set_fp(b,fp,BIO_NOCLOSE);
     93         ret=X509_print_ex(b, x, nmflag, cflag);
     94         BIO_free(b);
     95         return(ret);
     96         }
     97 #endif
     98 
     99 int X509_print(BIO *bp, X509 *x)
    100 {
    101 	return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
    102 }
    103 
    104 int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
    105 	{
    106 	long l;
    107 	int ret=0,i;
    108 	char *m=NULL,mlch = ' ';
    109 	int nmindent = 0;
    110 	X509_CINF *ci;
    111 	ASN1_INTEGER *bs;
    112 	EVP_PKEY *pkey=NULL;
    113 	const char *neg;
    114 	ASN1_STRING *str=NULL;
    115 
    116 	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
    117 			mlch = '\n';
    118 			nmindent = 12;
    119 	}
    120 
    121 	if(nmflags == X509_FLAG_COMPAT)
    122 		nmindent = 16;
    123 
    124 	ci=x->cert_info;
    125 	if(!(cflag & X509_FLAG_NO_HEADER))
    126 		{
    127 		if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
    128 		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
    129 		}
    130 	if(!(cflag & X509_FLAG_NO_VERSION))
    131 		{
    132 		l=X509_get_version(x);
    133 		if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
    134 		}
    135 	if(!(cflag & X509_FLAG_NO_SERIAL))
    136 		{
    137 
    138 		if (BIO_write(bp,"        Serial Number:",22) <= 0) goto err;
    139 
    140 		bs=X509_get_serialNumber(x);
    141 		if (bs->length <= 4)
    142 			{
    143 			l=ASN1_INTEGER_get(bs);
    144 			if (l < 0)
    145 				{
    146 				l= -l;
    147 				neg="-";
    148 				}
    149 			else
    150 				neg="";
    151 			if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
    152 				goto err;
    153 			}
    154 		else
    155 			{
    156 			neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
    157 			if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
    158 
    159 			for (i=0; i<bs->length; i++)
    160 				{
    161 				if (BIO_printf(bp,"%02x%c",bs->data[i],
    162 					((i+1 == bs->length)?'\n':':')) <= 0)
    163 					goto err;
    164 				}
    165 			}
    166 
    167 		}
    168 
    169 	if(!(cflag & X509_FLAG_NO_SIGNAME))
    170 		{
    171 		if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0)
    172 			goto err;
    173 		if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
    174 			goto err;
    175 		if (BIO_puts(bp, "\n") <= 0)
    176 			goto err;
    177 		}
    178 
    179 	if(!(cflag & X509_FLAG_NO_ISSUER))
    180 		{
    181 		if (BIO_printf(bp,"        Issuer:%c",mlch) <= 0) goto err;
    182 		if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
    183 		if (BIO_write(bp,"\n",1) <= 0) goto err;
    184 		}
    185 	if(!(cflag & X509_FLAG_NO_VALIDITY))
    186 		{
    187 		if (BIO_write(bp,"        Validity\n",17) <= 0) goto err;
    188 		if (BIO_write(bp,"            Not Before: ",24) <= 0) goto err;
    189 		if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
    190 		if (BIO_write(bp,"\n            Not After : ",25) <= 0) goto err;
    191 		if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
    192 		if (BIO_write(bp,"\n",1) <= 0) goto err;
    193 		}
    194 	if(!(cflag & X509_FLAG_NO_SUBJECT))
    195 		{
    196 		if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
    197 		if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
    198 		if (BIO_write(bp,"\n",1) <= 0) goto err;
    199 		}
    200 	if(!(cflag & X509_FLAG_NO_PUBKEY))
    201 		{
    202 		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
    203 			goto err;
    204 		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
    205 			goto err;
    206 		if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
    207 			goto err;
    208 		if (BIO_puts(bp, "\n") <= 0)
    209 			goto err;
    210 
    211 		pkey=X509_get_pubkey(x);
    212 		if (pkey == NULL)
    213 			{
    214 			BIO_printf(bp,"%12sUnable to load Public Key\n","");
    215 			ERR_print_errors(bp);
    216 			}
    217 		else
    218 #ifndef OPENSSL_NO_RSA
    219 		if (pkey->type == EVP_PKEY_RSA)
    220 			{
    221 			BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","",
    222 			BN_num_bits(pkey->pkey.rsa->n));
    223 			RSA_print(bp,pkey->pkey.rsa,16);
    224 			}
    225 		else
    226 #endif
    227 #ifndef OPENSSL_NO_DSA
    228 		if (pkey->type == EVP_PKEY_DSA)
    229 			{
    230 			BIO_printf(bp,"%12sDSA Public Key:\n","");
    231 			DSA_print(bp,pkey->pkey.dsa,16);
    232 			}
    233 		else
    234 #endif
    235 #ifndef OPENSSL_NO_EC
    236 		if (pkey->type == EVP_PKEY_EC)
    237 			{
    238 			BIO_printf(bp, "%12sEC Public Key:\n","");
    239 			EC_KEY_print(bp, pkey->pkey.ec, 16);
    240 			}
    241 		else
    242 #endif
    243 			BIO_printf(bp,"%12sUnknown Public Key:\n","");
    244 
    245 		EVP_PKEY_free(pkey);
    246 		}
    247 
    248 	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
    249 		X509V3_extensions_print(bp, "X509v3 extensions",
    250 					ci->extensions, cflag, 8);
    251 
    252 	if(!(cflag & X509_FLAG_NO_SIGDUMP))
    253 		{
    254 		if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
    255 		}
    256 	if(!(cflag & X509_FLAG_NO_AUX))
    257 		{
    258 		if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
    259 		}
    260 	ret=1;
    261 err:
    262 	if (str != NULL) ASN1_STRING_free(str);
    263 	if (m != NULL) OPENSSL_free(m);
    264 	return(ret);
    265 	}
    266 
    267 int X509_ocspid_print (BIO *bp, X509 *x)
    268 	{
    269 	unsigned char *der=NULL ;
    270 	unsigned char *dertmp;
    271 	int derlen;
    272 	int i;
    273 	unsigned char SHA1md[SHA_DIGEST_LENGTH];
    274 
    275 	/* display the hash of the subject as it would appear
    276 	   in OCSP requests */
    277 	if (BIO_printf(bp,"        Subject OCSP hash: ") <= 0)
    278 		goto err;
    279 	derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
    280 	if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
    281 		goto err;
    282 	i2d_X509_NAME(x->cert_info->subject, &dertmp);
    283 
    284 	EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL);
    285 	for (i=0; i < SHA_DIGEST_LENGTH; i++)
    286 		{
    287 		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
    288 		}
    289 	OPENSSL_free (der);
    290 	der=NULL;
    291 
    292 	/* display the hash of the public key as it would appear
    293 	   in OCSP requests */
    294 	if (BIO_printf(bp,"\n        Public key OCSP hash: ") <= 0)
    295 		goto err;
    296 
    297 	EVP_Digest(x->cert_info->key->public_key->data,
    298 		x->cert_info->key->public_key->length, SHA1md, NULL, EVP_sha1(), NULL);
    299 	for (i=0; i < SHA_DIGEST_LENGTH; i++)
    300 		{
    301 		if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
    302 			goto err;
    303 		}
    304 	BIO_printf(bp,"\n");
    305 
    306 	return (1);
    307 err:
    308 	if (der != NULL) OPENSSL_free(der);
    309 	return(0);
    310 	}
    311 
    312 int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
    313 {
    314 	unsigned char *s;
    315 	int i, n;
    316 	if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
    317 	if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
    318 
    319 	n=sig->length;
    320 	s=sig->data;
    321 	for (i=0; i<n; i++)
    322 		{
    323 		if ((i%18) == 0)
    324 			if (BIO_write(bp,"\n        ",9) <= 0) return 0;
    325 			if (BIO_printf(bp,"%02x%s",s[i],
    326 				((i+1) == n)?"":":") <= 0) return 0;
    327 		}
    328 	if (BIO_write(bp,"\n",1) != 1) return 0;
    329 	return 1;
    330 }
    331 
    332 int ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
    333 	{
    334 	int i,n;
    335 	char buf[80],*p;
    336 
    337 	if (v == NULL) return(0);
    338 	n=0;
    339 	p=(char *)v->data;
    340 	for (i=0; i<v->length; i++)
    341 		{
    342 		if ((p[i] > '~') || ((p[i] < ' ') &&
    343 			(p[i] != '\n') && (p[i] != '\r')))
    344 			buf[n]='.';
    345 		else
    346 			buf[n]=p[i];
    347 		n++;
    348 		if (n >= 80)
    349 			{
    350 			if (BIO_write(bp,buf,n) <= 0)
    351 				return(0);
    352 			n=0;
    353 			}
    354 		}
    355 	if (n > 0)
    356 		if (BIO_write(bp,buf,n) <= 0)
    357 			return(0);
    358 	return(1);
    359 	}
    360 
    361 int ASN1_TIME_print(BIO *bp, ASN1_TIME *tm)
    362 {
    363 	if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
    364 	if(tm->type == V_ASN1_GENERALIZEDTIME)
    365 				return ASN1_GENERALIZEDTIME_print(bp, tm);
    366 	BIO_write(bp,"Bad time value",14);
    367 	return(0);
    368 }
    369 
    370 static const char *mon[12]=
    371     {
    372     "Jan","Feb","Mar","Apr","May","Jun",
    373     "Jul","Aug","Sep","Oct","Nov","Dec"
    374     };
    375 
    376 int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
    377 	{
    378 	char *v;
    379 	int gmt=0;
    380 	int i;
    381 	int y=0,M=0,d=0,h=0,m=0,s=0;
    382 	char *f = NULL;
    383 	int f_len = 0;
    384 
    385 	i=tm->length;
    386 	v=(char *)tm->data;
    387 
    388 	if (i < 12) goto err;
    389 	if (v[i-1] == 'Z') gmt=1;
    390 	for (i=0; i<12; i++)
    391 		if ((v[i] > '9') || (v[i] < '0')) goto err;
    392 	y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
    393 	M= (v[4]-'0')*10+(v[5]-'0');
    394 	if ((M > 12) || (M < 1)) goto err;
    395 	d= (v[6]-'0')*10+(v[7]-'0');
    396 	h= (v[8]-'0')*10+(v[9]-'0');
    397 	m=  (v[10]-'0')*10+(v[11]-'0');
    398 	if (tm->length >= 14 &&
    399 	    (v[12] >= '0') && (v[12] <= '9') &&
    400 	    (v[13] >= '0') && (v[13] <= '9'))
    401 		{
    402 		s=  (v[12]-'0')*10+(v[13]-'0');
    403 		/* Check for fractions of seconds. */
    404 		if (tm->length >= 15 && v[14] == '.')
    405 			{
    406 			int l = tm->length;
    407 			f = &v[14];	/* The decimal point. */
    408 			f_len = 1;
    409 			while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
    410 				++f_len;
    411 			}
    412 		}
    413 
    414 	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
    415 		mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
    416 		return(0);
    417 	else
    418 		return(1);
    419 err:
    420 	BIO_write(bp,"Bad time value",14);
    421 	return(0);
    422 	}
    423 
    424 int ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm)
    425 	{
    426 	char *v;
    427 	int gmt=0;
    428 	int i;
    429 	int y=0,M=0,d=0,h=0,m=0,s=0;
    430 
    431 	i=tm->length;
    432 	v=(char *)tm->data;
    433 
    434 	if (i < 10) goto err;
    435 	if (v[i-1] == 'Z') gmt=1;
    436 	for (i=0; i<10; i++)
    437 		if ((v[i] > '9') || (v[i] < '0')) goto err;
    438 	y= (v[0]-'0')*10+(v[1]-'0');
    439 	if (y < 50) y+=100;
    440 	M= (v[2]-'0')*10+(v[3]-'0');
    441 	if ((M > 12) || (M < 1)) goto err;
    442 	d= (v[4]-'0')*10+(v[5]-'0');
    443 	h= (v[6]-'0')*10+(v[7]-'0');
    444 	m=  (v[8]-'0')*10+(v[9]-'0');
    445 	if (tm->length >=12 &&
    446 	    (v[10] >= '0') && (v[10] <= '9') &&
    447 	    (v[11] >= '0') && (v[11] <= '9'))
    448 		s=  (v[10]-'0')*10+(v[11]-'0');
    449 
    450 	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
    451 		mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
    452 		return(0);
    453 	else
    454 		return(1);
    455 err:
    456 	BIO_write(bp,"Bad time value",14);
    457 	return(0);
    458 	}
    459 
    460 int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
    461 	{
    462 	char *s,*c,*b;
    463 	int ret=0,l,i;
    464 
    465 	l=80-2-obase;
    466 
    467 	b=X509_NAME_oneline(name,NULL,0);
    468 	if (!*b)
    469 		{
    470 		OPENSSL_free(b);
    471 		return 1;
    472 		}
    473 	s=b+1; /* skip the first slash */
    474 
    475 	c=s;
    476 	for (;;)
    477 		{
    478 #ifndef CHARSET_EBCDIC
    479 		if (	((*s == '/') &&
    480 				((s[1] >= 'A') && (s[1] <= 'Z') && (
    481 					(s[2] == '=') ||
    482 					((s[2] >= 'A') && (s[2] <= 'Z') &&
    483 					(s[3] == '='))
    484 				 ))) ||
    485 			(*s == '\0'))
    486 #else
    487 		if (	((*s == '/') &&
    488 				(isupper(s[1]) && (
    489 					(s[2] == '=') ||
    490 					(isupper(s[2]) &&
    491 					(s[3] == '='))
    492 				 ))) ||
    493 			(*s == '\0'))
    494 #endif
    495 			{
    496 			i=s-c;
    497 			if (BIO_write(bp,c,i) != i) goto err;
    498 			c=s+1;	/* skip following slash */
    499 			if (*s != '\0')
    500 				{
    501 				if (BIO_write(bp,", ",2) != 2) goto err;
    502 				}
    503 			l--;
    504 			}
    505 		if (*s == '\0') break;
    506 		s++;
    507 		l--;
    508 		}
    509 
    510 	ret=1;
    511 	if (0)
    512 		{
    513 err:
    514 		X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
    515 		}
    516 	OPENSSL_free(b);
    517 	return(ret);
    518 	}
    519