1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/certhigh/certhtml.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,299 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * certhtml.c --- convert a cert to html 1.10 + */ 1.11 + 1.12 +#include "seccomon.h" 1.13 +#include "secitem.h" 1.14 +#include "sechash.h" 1.15 +#include "cert.h" 1.16 +#include "keyhi.h" 1.17 +#include "secder.h" 1.18 +#include "prprf.h" 1.19 +#include "secport.h" 1.20 +#include "secasn1.h" 1.21 +#include "pk11func.h" 1.22 + 1.23 +static char *hex = "0123456789ABCDEF"; 1.24 + 1.25 +/* 1.26 +** Convert a der-encoded integer to a hex printable string form 1.27 +*/ 1.28 +char *CERT_Hexify (SECItem *i, int do_colon) 1.29 +{ 1.30 + unsigned char *cp, *end; 1.31 + char *rv, *o; 1.32 + 1.33 + if (!i->len) { 1.34 + return PORT_Strdup("00"); 1.35 + } 1.36 + 1.37 + rv = o = (char*) PORT_Alloc(i->len * 3); 1.38 + if (!rv) return rv; 1.39 + 1.40 + cp = i->data; 1.41 + end = cp + i->len; 1.42 + while (cp < end) { 1.43 + unsigned char ch = *cp++; 1.44 + *o++ = hex[(ch >> 4) & 0xf]; 1.45 + *o++ = hex[ch & 0xf]; 1.46 + if (cp != end) { 1.47 + if (do_colon) { 1.48 + *o++ = ':'; 1.49 + } 1.50 + } 1.51 + } 1.52 + *o = 0; /* Null terminate the string */ 1.53 + return rv; 1.54 +} 1.55 + 1.56 +#define BREAK "<br>" 1.57 +#define BREAKLEN 4 1.58 +#define COMMA ", " 1.59 +#define COMMALEN 2 1.60 + 1.61 +#define MAX_OUS 20 1.62 +#define MAX_DC MAX_OUS 1.63 + 1.64 + 1.65 +char *CERT_FormatName (CERTName *name) 1.66 +{ 1.67 + CERTRDN** rdns; 1.68 + CERTRDN * rdn; 1.69 + CERTAVA** avas; 1.70 + CERTAVA* ava; 1.71 + char * buf = 0; 1.72 + char * tmpbuf = 0; 1.73 + SECItem * cn = 0; 1.74 + SECItem * email = 0; 1.75 + SECItem * org = 0; 1.76 + SECItem * loc = 0; 1.77 + SECItem * state = 0; 1.78 + SECItem * country = 0; 1.79 + SECItem * dq = 0; 1.80 + 1.81 + unsigned len = 0; 1.82 + int tag; 1.83 + int i; 1.84 + int ou_count = 0; 1.85 + int dc_count = 0; 1.86 + PRBool first; 1.87 + SECItem * orgunit[MAX_OUS]; 1.88 + SECItem * dc[MAX_DC]; 1.89 + 1.90 + /* Loop over name components and gather the interesting ones */ 1.91 + rdns = name->rdns; 1.92 + while ((rdn = *rdns++) != 0) { 1.93 + avas = rdn->avas; 1.94 + while ((ava = *avas++) != 0) { 1.95 + tag = CERT_GetAVATag(ava); 1.96 + switch(tag) { 1.97 + case SEC_OID_AVA_COMMON_NAME: 1.98 + if (cn) { 1.99 + break; 1.100 + } 1.101 + cn = CERT_DecodeAVAValue(&ava->value); 1.102 + if (!cn) { 1.103 + goto loser; 1.104 + } 1.105 + len += cn->len; 1.106 + break; 1.107 + case SEC_OID_AVA_COUNTRY_NAME: 1.108 + if (country) { 1.109 + break; 1.110 + } 1.111 + country = CERT_DecodeAVAValue(&ava->value); 1.112 + if (!country) { 1.113 + goto loser; 1.114 + } 1.115 + len += country->len; 1.116 + break; 1.117 + case SEC_OID_AVA_LOCALITY: 1.118 + if (loc) { 1.119 + break; 1.120 + } 1.121 + loc = CERT_DecodeAVAValue(&ava->value); 1.122 + if (!loc) { 1.123 + goto loser; 1.124 + } 1.125 + len += loc->len; 1.126 + break; 1.127 + case SEC_OID_AVA_STATE_OR_PROVINCE: 1.128 + if (state) { 1.129 + break; 1.130 + } 1.131 + state = CERT_DecodeAVAValue(&ava->value); 1.132 + if (!state) { 1.133 + goto loser; 1.134 + } 1.135 + len += state->len; 1.136 + break; 1.137 + case SEC_OID_AVA_ORGANIZATION_NAME: 1.138 + if (org) { 1.139 + break; 1.140 + } 1.141 + org = CERT_DecodeAVAValue(&ava->value); 1.142 + if (!org) { 1.143 + goto loser; 1.144 + } 1.145 + len += org->len; 1.146 + break; 1.147 + case SEC_OID_AVA_DN_QUALIFIER: 1.148 + if (dq) { 1.149 + break; 1.150 + } 1.151 + dq = CERT_DecodeAVAValue(&ava->value); 1.152 + if (!dq) { 1.153 + goto loser; 1.154 + } 1.155 + len += dq->len; 1.156 + break; 1.157 + case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: 1.158 + if (ou_count < MAX_OUS) { 1.159 + orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value); 1.160 + if (!orgunit[ou_count]) { 1.161 + goto loser; 1.162 + } 1.163 + len += orgunit[ou_count++]->len; 1.164 + } 1.165 + break; 1.166 + case SEC_OID_AVA_DC: 1.167 + if (dc_count < MAX_DC) { 1.168 + dc[dc_count] = CERT_DecodeAVAValue(&ava->value); 1.169 + if (!dc[dc_count]) { 1.170 + goto loser; 1.171 + } 1.172 + len += dc[dc_count++]->len; 1.173 + } 1.174 + break; 1.175 + case SEC_OID_PKCS9_EMAIL_ADDRESS: 1.176 + case SEC_OID_RFC1274_MAIL: 1.177 + if (email) { 1.178 + break; 1.179 + } 1.180 + email = CERT_DecodeAVAValue(&ava->value); 1.181 + if (!email) { 1.182 + goto loser; 1.183 + } 1.184 + len += email->len; 1.185 + break; 1.186 + default: 1.187 + break; 1.188 + } 1.189 + } 1.190 + } 1.191 + 1.192 + /* XXX - add some for formatting */ 1.193 + len += 128; 1.194 + 1.195 + /* allocate buffer */ 1.196 + buf = (char *)PORT_Alloc(len); 1.197 + if ( !buf ) { 1.198 + goto loser; 1.199 + } 1.200 + 1.201 + tmpbuf = buf; 1.202 + 1.203 + if ( cn ) { 1.204 + PORT_Memcpy(tmpbuf, cn->data, cn->len); 1.205 + tmpbuf += cn->len; 1.206 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.207 + tmpbuf += BREAKLEN; 1.208 + } 1.209 + if ( email ) { 1.210 + PORT_Memcpy(tmpbuf, email->data, email->len); 1.211 + tmpbuf += ( email->len ); 1.212 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.213 + tmpbuf += BREAKLEN; 1.214 + } 1.215 + for (i=ou_count-1; i >= 0; i--) { 1.216 + PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len); 1.217 + tmpbuf += ( orgunit[i]->len ); 1.218 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.219 + tmpbuf += BREAKLEN; 1.220 + } 1.221 + if ( dq ) { 1.222 + PORT_Memcpy(tmpbuf, dq->data, dq->len); 1.223 + tmpbuf += ( dq->len ); 1.224 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.225 + tmpbuf += BREAKLEN; 1.226 + } 1.227 + if ( org ) { 1.228 + PORT_Memcpy(tmpbuf, org->data, org->len); 1.229 + tmpbuf += ( org->len ); 1.230 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.231 + tmpbuf += BREAKLEN; 1.232 + } 1.233 + for (i=dc_count-1; i >= 0; i--) { 1.234 + PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len); 1.235 + tmpbuf += ( dc[i]->len ); 1.236 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.237 + tmpbuf += BREAKLEN; 1.238 + } 1.239 + first = PR_TRUE; 1.240 + if ( loc ) { 1.241 + PORT_Memcpy(tmpbuf, loc->data, loc->len); 1.242 + tmpbuf += ( loc->len ); 1.243 + first = PR_FALSE; 1.244 + } 1.245 + if ( state ) { 1.246 + if ( !first ) { 1.247 + PORT_Memcpy(tmpbuf, COMMA, COMMALEN); 1.248 + tmpbuf += COMMALEN; 1.249 + } 1.250 + PORT_Memcpy(tmpbuf, state->data, state->len); 1.251 + tmpbuf += ( state->len ); 1.252 + first = PR_FALSE; 1.253 + } 1.254 + if ( country ) { 1.255 + if ( !first ) { 1.256 + PORT_Memcpy(tmpbuf, COMMA, COMMALEN); 1.257 + tmpbuf += COMMALEN; 1.258 + } 1.259 + PORT_Memcpy(tmpbuf, country->data, country->len); 1.260 + tmpbuf += ( country->len ); 1.261 + first = PR_FALSE; 1.262 + } 1.263 + if ( !first ) { 1.264 + PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); 1.265 + tmpbuf += BREAKLEN; 1.266 + } 1.267 + 1.268 + *tmpbuf = 0; 1.269 + 1.270 + /* fall through and clean */ 1.271 +loser: 1.272 + if ( cn ) { 1.273 + SECITEM_FreeItem(cn, PR_TRUE); 1.274 + } 1.275 + if ( email ) { 1.276 + SECITEM_FreeItem(email, PR_TRUE); 1.277 + } 1.278 + for (i=ou_count-1; i >= 0; i--) { 1.279 + SECITEM_FreeItem(orgunit[i], PR_TRUE); 1.280 + } 1.281 + if ( dq ) { 1.282 + SECITEM_FreeItem(dq, PR_TRUE); 1.283 + } 1.284 + if ( org ) { 1.285 + SECITEM_FreeItem(org, PR_TRUE); 1.286 + } 1.287 + for (i=dc_count-1; i >= 0; i--) { 1.288 + SECITEM_FreeItem(dc[i], PR_TRUE); 1.289 + } 1.290 + if ( loc ) { 1.291 + SECITEM_FreeItem(loc, PR_TRUE); 1.292 + } 1.293 + if ( state ) { 1.294 + SECITEM_FreeItem(state, PR_TRUE); 1.295 + } 1.296 + if ( country ) { 1.297 + SECITEM_FreeItem(country, PR_TRUE); 1.298 + } 1.299 + 1.300 + return(buf); 1.301 +} 1.302 +