xauthkid.c (4017B)
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/. */ 4 5 /* 6 * X.509 v3 Subject Key Usage Extension 7 * 8 */ 9 10 #include "prtypes.h" 11 #include "seccomon.h" 12 #include "secdert.h" 13 #include "secoidt.h" 14 #include "secasn1t.h" 15 #include "secasn1.h" 16 #include "secport.h" 17 #include "certt.h" 18 #include "genname.h" 19 #include "secerr.h" 20 21 SEC_ASN1_MKSUB(SEC_IntegerTemplate) 22 SEC_ASN1_MKSUB(SEC_OctetStringTemplate) 23 24 const SEC_ASN1Template CERTAuthKeyIDTemplate[] = { 25 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) }, 26 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 27 offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) }, 28 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 29 offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate }, 30 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, 31 offsetof(CERTAuthKeyID, authCertSerialNumber), 32 SEC_ASN1_SUB(SEC_IntegerTemplate) }, 33 { 0 } 34 }; 35 36 SECStatus 37 CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value, 38 SECItem *encodedValue) 39 { 40 SECStatus rv = SECFailure; 41 42 PORT_Assert(value); 43 PORT_Assert(arena); 44 PORT_Assert(value->DERAuthCertIssuer == NULL); 45 PORT_Assert(encodedValue); 46 47 do { 48 49 /* If both of the authCertIssuer and the serial number exist, encode 50 the name first. Otherwise, it is an error if one exist and the other 51 is not. 52 */ 53 if (value->authCertIssuer) { 54 if (!value->authCertSerialNumber.data) { 55 PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID); 56 break; 57 } 58 59 value->DERAuthCertIssuer = 60 cert_EncodeGeneralNames(arena, value->authCertIssuer); 61 if (!value->DERAuthCertIssuer) { 62 PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID); 63 break; 64 } 65 } else if (value->authCertSerialNumber.data) { 66 PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID); 67 break; 68 } 69 70 if (SEC_ASN1EncodeItem(arena, encodedValue, value, 71 CERTAuthKeyIDTemplate) == NULL) 72 break; 73 rv = SECSuccess; 74 75 } while (0); 76 return (rv); 77 } 78 79 CERTAuthKeyID * 80 CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue) 81 { 82 CERTAuthKeyID *value = NULL; 83 SECStatus rv = SECFailure; 84 void *mark; 85 SECItem newEncodedValue; 86 87 PORT_Assert(arena); 88 89 do { 90 mark = PORT_ArenaMark(arena); 91 value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value)); 92 if (value == NULL) 93 break; 94 value->DERAuthCertIssuer = NULL; 95 /* copy the DER into the arena, since Quick DER returns data that points 96 into the DER input, which may get freed by the caller */ 97 rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); 98 if (rv != SECSuccess) { 99 break; 100 } 101 102 rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate, 103 &newEncodedValue); 104 if (rv != SECSuccess) 105 break; 106 107 value->authCertIssuer = 108 cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer); 109 if (value->authCertIssuer == NULL) 110 break; 111 112 /* what if the general name contains other format but not URI ? 113 hl 114 */ 115 if ((value->authCertSerialNumber.data && !value->authCertIssuer) || 116 (!value->authCertSerialNumber.data && value->authCertIssuer)) { 117 PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID); 118 break; 119 } 120 } while (0); 121 122 if (rv != SECSuccess) { 123 PORT_ArenaRelease(arena, mark); 124 return ((CERTAuthKeyID *)NULL); 125 } 126 PORT_ArenaUnmark(arena, mark); 127 return (value); 128 }