security/nss/lib/certhigh/certhtml.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * certhtml.c --- convert a cert to html
     7  */
     9 #include "seccomon.h"
    10 #include "secitem.h"
    11 #include "sechash.h"
    12 #include "cert.h"
    13 #include "keyhi.h"
    14 #include "secder.h"
    15 #include "prprf.h"
    16 #include "secport.h"
    17 #include "secasn1.h"
    18 #include "pk11func.h"
    20 static char *hex = "0123456789ABCDEF";
    22 /*
    23 ** Convert a der-encoded integer to a hex printable string form
    24 */
    25 char *CERT_Hexify (SECItem *i, int do_colon)
    26 {
    27     unsigned char *cp, *end;
    28     char *rv, *o;
    30     if (!i->len) {
    31 	return PORT_Strdup("00");
    32     }
    34     rv = o = (char*) PORT_Alloc(i->len * 3);
    35     if (!rv) return rv;
    37     cp = i->data;
    38     end = cp + i->len;
    39     while (cp < end) {
    40 	unsigned char ch = *cp++;
    41 	*o++ = hex[(ch >> 4) & 0xf];
    42 	*o++ = hex[ch & 0xf];
    43 	if (cp != end) {
    44 	    if (do_colon) {
    45 		*o++ = ':';
    46 	    }
    47 	} 
    48     }
    49     *o = 0;           /* Null terminate the string */
    50     return rv;
    51 }
    53 #define BREAK "<br>"
    54 #define BREAKLEN 4
    55 #define COMMA ", "
    56 #define COMMALEN 2
    58 #define MAX_OUS 20
    59 #define MAX_DC MAX_OUS
    62 char *CERT_FormatName (CERTName *name)
    63 {
    64     CERTRDN** rdns;
    65     CERTRDN * rdn;
    66     CERTAVA** avas;
    67     CERTAVA*  ava;
    68     char *    buf	= 0;
    69     char *    tmpbuf	= 0;
    70     SECItem * cn	= 0;
    71     SECItem * email	= 0;
    72     SECItem * org	= 0;
    73     SECItem * loc	= 0;
    74     SECItem * state	= 0;
    75     SECItem * country	= 0;
    76     SECItem * dq     	= 0;
    78     unsigned  len 	= 0;
    79     int       tag;
    80     int       i;
    81     int       ou_count = 0;
    82     int       dc_count = 0;
    83     PRBool    first;
    84     SECItem * orgunit[MAX_OUS];
    85     SECItem * dc[MAX_DC];
    87     /* Loop over name components and gather the interesting ones */
    88     rdns = name->rdns;
    89     while ((rdn = *rdns++) != 0) {
    90 	avas = rdn->avas;
    91 	while ((ava = *avas++) != 0) {
    92 	    tag = CERT_GetAVATag(ava);
    93 	    switch(tag) {
    94 	      case SEC_OID_AVA_COMMON_NAME:
    95 		if (cn) {
    96 			break;
    97 		}
    98 		cn = CERT_DecodeAVAValue(&ava->value);
    99 		if (!cn) {
   100  			goto loser;
   101 		}
   102 		len += cn->len;
   103 		break;
   104 	      case SEC_OID_AVA_COUNTRY_NAME:
   105 		if (country) {
   106 			break;
   107 		}
   108 		country = CERT_DecodeAVAValue(&ava->value);
   109 		if (!country) {
   110  			goto loser;
   111 		}
   112 		len += country->len;
   113 		break;
   114 	      case SEC_OID_AVA_LOCALITY:
   115 		if (loc) {
   116 			break;
   117 		}
   118 		loc = CERT_DecodeAVAValue(&ava->value);
   119 		if (!loc) {
   120  			goto loser;
   121 		}
   122 		len += loc->len;
   123 		break;
   124 	      case SEC_OID_AVA_STATE_OR_PROVINCE:
   125 		if (state) {
   126 			break;
   127 		}
   128 		state = CERT_DecodeAVAValue(&ava->value);
   129 		if (!state) {
   130  			goto loser;
   131 		}
   132 		len += state->len;
   133 		break;
   134 	      case SEC_OID_AVA_ORGANIZATION_NAME:
   135 		if (org) {
   136 			break;
   137 		}
   138 		org = CERT_DecodeAVAValue(&ava->value);
   139 		if (!org) {
   140  			goto loser;
   141 		}
   142 		len += org->len;
   143 		break;
   144 	      case SEC_OID_AVA_DN_QUALIFIER:
   145 		if (dq) {
   146 			break;
   147 		}
   148 		dq = CERT_DecodeAVAValue(&ava->value);
   149 		if (!dq) {
   150  			goto loser;
   151 		}
   152 		len += dq->len;
   153 		break;
   154 	      case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
   155 		if (ou_count < MAX_OUS) {
   156 			orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
   157 			if (!orgunit[ou_count]) {
   158 				goto loser;
   159                         }
   160 			len += orgunit[ou_count++]->len;
   161 		}
   162 		break;
   163 	      case SEC_OID_AVA_DC:
   164 		if (dc_count < MAX_DC) {
   165 			dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
   166 			if (!dc[dc_count]) {
   167 				goto loser;
   168 			}
   169 			len += dc[dc_count++]->len;
   170 		}
   171 		break;
   172 	      case SEC_OID_PKCS9_EMAIL_ADDRESS:
   173 	      case SEC_OID_RFC1274_MAIL:
   174 		if (email) {
   175 			break;
   176 		}
   177 		email = CERT_DecodeAVAValue(&ava->value);
   178 		if (!email) {
   179 			goto loser;
   180 		}
   181 		len += email->len;
   182 		break;
   183 	      default:
   184 		break;
   185 	    }
   186 	}
   187     }
   189     /* XXX - add some for formatting */
   190     len += 128;
   192     /* allocate buffer */
   193     buf = (char *)PORT_Alloc(len);
   194     if ( !buf ) {
   195 	goto loser;
   196     }
   198     tmpbuf = buf;
   200     if ( cn ) {
   201 	PORT_Memcpy(tmpbuf, cn->data, cn->len);
   202 	tmpbuf += cn->len;
   203 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   204 	tmpbuf += BREAKLEN;
   205     }
   206     if ( email ) {
   207 	PORT_Memcpy(tmpbuf, email->data, email->len);
   208 	tmpbuf += ( email->len );
   209 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   210 	tmpbuf += BREAKLEN;
   211     }
   212     for (i=ou_count-1; i >= 0; i--) {
   213 	PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
   214 	tmpbuf += ( orgunit[i]->len );
   215 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   216 	tmpbuf += BREAKLEN;
   217     }
   218     if ( dq ) {
   219 	PORT_Memcpy(tmpbuf, dq->data, dq->len);
   220 	tmpbuf += ( dq->len );
   221 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   222 	tmpbuf += BREAKLEN;
   223     }
   224     if ( org ) {
   225 	PORT_Memcpy(tmpbuf, org->data, org->len);
   226 	tmpbuf += ( org->len );
   227 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   228 	tmpbuf += BREAKLEN;
   229     }
   230     for (i=dc_count-1; i >= 0; i--) {
   231 	PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
   232 	tmpbuf += ( dc[i]->len );
   233 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   234 	tmpbuf += BREAKLEN;
   235     }
   236     first = PR_TRUE;
   237     if ( loc ) {
   238 	PORT_Memcpy(tmpbuf, loc->data,  loc->len);
   239 	tmpbuf += ( loc->len );
   240 	first = PR_FALSE;
   241     }
   242     if ( state ) {
   243 	if ( !first ) {
   244 	    PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
   245 	    tmpbuf += COMMALEN;
   246 	}
   247 	PORT_Memcpy(tmpbuf, state->data, state->len);
   248 	tmpbuf += ( state->len );
   249 	first = PR_FALSE;
   250     }
   251     if ( country ) {
   252 	if ( !first ) {
   253 	    PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
   254 	    tmpbuf += COMMALEN;
   255 	}
   256 	PORT_Memcpy(tmpbuf, country->data, country->len);
   257 	tmpbuf += ( country->len );
   258 	first = PR_FALSE;
   259     }
   260     if ( !first ) {
   261 	PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
   262 	tmpbuf += BREAKLEN;
   263     }
   265     *tmpbuf = 0;
   267     /* fall through and clean */
   268 loser:
   269     if ( cn ) {
   270 	SECITEM_FreeItem(cn, PR_TRUE);
   271     }
   272     if ( email ) {
   273 	SECITEM_FreeItem(email, PR_TRUE);
   274     }
   275     for (i=ou_count-1; i >= 0; i--) {
   276 	SECITEM_FreeItem(orgunit[i], PR_TRUE);
   277     }
   278     if ( dq ) {
   279 	SECITEM_FreeItem(dq, PR_TRUE);
   280     }
   281     if ( org ) {
   282 	SECITEM_FreeItem(org, PR_TRUE);
   283     }
   284     for (i=dc_count-1; i >= 0; i--) {
   285 	SECITEM_FreeItem(dc[i], PR_TRUE);
   286     }
   287     if ( loc ) {
   288 	SECITEM_FreeItem(loc, PR_TRUE);
   289     }
   290     if ( state ) {
   291 	SECITEM_FreeItem(state, PR_TRUE);
   292     }
   293     if ( country ) {
   294 	SECITEM_FreeItem(country, PR_TRUE);
   295     }
   297     return(buf);
   298 }

mercurial