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

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

mercurial