| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 /* | 5 /* |
| 6 * Code for dealing with X509.V3 extensions. | 6 * Code for dealing with X509.V3 extensions. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "cert.h" | 9 #include "cert.h" |
| 10 #include "secitem.h" | 10 #include "secitem.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 cert->extensions = exts; | 36 cert->extensions = exts; |
| 37 DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); | 37 DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void * | 40 void * |
| 41 CERT_StartCertExtensions(CERTCertificate *cert) | 41 CERT_StartCertExtensions(CERTCertificate *cert) |
| 42 { | 42 { |
| 43 return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); | 43 return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); |
| 44 } | 44 } |
| 45 | 45 |
| 46 /* find the given extension in the certificate of the Issuer of 'cert' */ | |
| 47 SECStatus | |
| 48 CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value) | |
| 49 { | |
| 50 CERTCertificate *issuercert; | |
| 51 SECStatus rv; | |
| 52 | |
| 53 issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer); | |
| 54 if ( issuercert ) { | |
| 55 rv = cert_FindExtension(issuercert->extensions, tag, value); | |
| 56 CERT_DestroyCertificate(issuercert); | |
| 57 } else { | |
| 58 rv = SECFailure; | |
| 59 } | |
| 60 | |
| 61 return(rv); | |
| 62 } | |
| 63 | |
| 64 /* find a URL extension in the cert or its CA | |
| 65 * apply the base URL string if it exists | |
| 66 */ | |
| 67 char * | |
| 68 CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag) | |
| 69 { | |
| 70 SECStatus rv; | |
| 71 SECItem urlitem = {siBuffer,0}; | |
| 72 SECItem baseitem = {siBuffer,0}; | |
| 73 SECItem urlstringitem = {siBuffer,0}; | |
| 74 SECItem basestringitem = {siBuffer,0}; | |
| 75 PLArenaPool *arena = NULL; | |
| 76 PRBool hasbase; | |
| 77 char *urlstring; | |
| 78 char *str; | |
| 79 int len; | |
| 80 unsigned int i; | |
| 81 | |
| 82 urlstring = NULL; | |
| 83 | |
| 84 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
| 85 if ( ! arena ) { | |
| 86 goto loser; | |
| 87 } | |
| 88 | |
| 89 hasbase = PR_FALSE; | |
| 90 | |
| 91 rv = cert_FindExtension(cert->extensions, tag, &urlitem); | |
| 92 if ( rv == SECSuccess ) { | |
| 93 rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL, | |
| 94 &baseitem); | |
| 95 if ( rv == SECSuccess ) { | |
| 96 hasbase = PR_TRUE; | |
| 97 } | |
| 98 | |
| 99 } else if ( catag ) { | |
| 100 /* if the cert doesn't have the extensions, see if the issuer does */ | |
| 101 rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem); | |
| 102 if ( rv != SECSuccess ) { | |
| 103 goto loser; | |
| 104 } | |
| 105 rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL, | |
| 106 &baseitem); | |
| 107 if ( rv == SECSuccess ) { | |
| 108 hasbase = PR_TRUE; | |
| 109 } | |
| 110 } else { | |
| 111 goto loser; | |
| 112 } | |
| 113 | |
| 114 rv = SEC_QuickDERDecodeItem(arena, &urlstringitem, | |
| 115 SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem); | |
| 116 | |
| 117 if ( rv != SECSuccess ) { | |
| 118 goto loser; | |
| 119 } | |
| 120 if ( hasbase ) { | |
| 121 rv = SEC_QuickDERDecodeItem(arena, &basestringitem, | |
| 122 SEC_ASN1_GET(SEC_IA5StringTemplate), | |
| 123 &baseitem); | |
| 124 | |
| 125 if ( rv != SECSuccess ) { | |
| 126 goto loser; | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 len = urlstringitem.len + ( hasbase ? basestringitem.len : 0 ) + 1; | |
| 131 | |
| 132 str = urlstring = (char *)PORT_Alloc(len); | |
| 133 if ( urlstring == NULL ) { | |
| 134 goto loser; | |
| 135 } | |
| 136 | |
| 137 /* copy the URL base first */ | |
| 138 if ( hasbase ) { | |
| 139 | |
| 140 /* if the urlstring has a : in it, then we assume it is an absolute | |
| 141 * URL, and will not get the base string pre-pended | |
| 142 */ | |
| 143 for ( i = 0; i < urlstringitem.len; i++ ) { | |
| 144 if ( urlstringitem.data[i] == ':' ) { | |
| 145 goto nobase; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 PORT_Memcpy(str, basestringitem.data, basestringitem.len); | |
| 150 str += basestringitem.len; | |
| 151 | |
| 152 } | |
| 153 | |
| 154 nobase: | |
| 155 /* copy the rest (or all) of the URL */ | |
| 156 PORT_Memcpy(str, urlstringitem.data, urlstringitem.len); | |
| 157 str += urlstringitem.len; | |
| 158 | |
| 159 *str = '\0'; | |
| 160 goto done; | |
| 161 | |
| 162 loser: | |
| 163 if ( urlstring ) { | |
| 164 PORT_Free(urlstring); | |
| 165 } | |
| 166 | |
| 167 urlstring = NULL; | |
| 168 done: | |
| 169 if ( arena ) { | |
| 170 PORT_FreeArena(arena, PR_FALSE); | |
| 171 } | |
| 172 if ( baseitem.data ) { | |
| 173 PORT_Free(baseitem.data); | |
| 174 } | |
| 175 if ( urlitem.data ) { | |
| 176 PORT_Free(urlitem.data); | |
| 177 } | |
| 178 | |
| 179 return(urlstring); | |
| 180 } | |
| 181 | |
| 182 /* | 46 /* |
| 183 * get the value of the Netscape Certificate Type Extension | 47 * get the value of the Netscape Certificate Type Extension |
| 184 */ | 48 */ |
| 185 SECStatus | 49 SECStatus |
| 186 CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem) | 50 CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem) |
| 187 { | 51 { |
| 188 | 52 |
| 189 return (CERT_FindBitStringExtension | 53 return (CERT_FindBitStringExtension |
| 190 (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem)); | 54 (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem)); |
| 191 } | 55 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 if (rv == SECFailure) { | 220 if (rv == SECFailure) { |
| 357 rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? | 221 rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? |
| 358 SECSuccess : SECFailure; | 222 SECSuccess : SECFailure; |
| 359 } else if (!(keyUsage.data[0] & usage)) { | 223 } else if (!(keyUsage.data[0] & usage)) { |
| 360 PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID); | 224 PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID); |
| 361 rv = SECFailure; | 225 rv = SECFailure; |
| 362 } | 226 } |
| 363 PORT_Free (keyUsage.data); | 227 PORT_Free (keyUsage.data); |
| 364 return (rv); | 228 return (rv); |
| 365 } | 229 } |
| OLD | NEW |