asn1cmn.c (7451B)
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 #include "cmmf.h" 6 #include "cmmfi.h" 7 8 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 9 SEC_ASN1_MKSUB(SEC_AnyTemplate) 10 SEC_ASN1_MKSUB(SEC_IntegerTemplate) 11 SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate) 12 13 static const SEC_ASN1Template CMMFCertResponseTemplate[] = { 14 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertResponse) }, 15 { SEC_ASN1_INTEGER, offsetof(CMMFCertResponse, certReqId) }, 16 { SEC_ASN1_INLINE, offsetof(CMMFCertResponse, status), 17 CMMFPKIStatusInfoTemplate }, 18 { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER, 19 offsetof(CMMFCertResponse, certifiedKeyPair), 20 CMMFCertifiedKeyPairTemplate }, 21 { 0 } 22 }; 23 24 static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = { 25 { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL, 26 sizeof(CMMFCertOrEncCert) }, 27 { 0 } 28 }; 29 30 const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = { 31 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair) }, 32 { SEC_ASN1_INLINE, offsetof(CMMFCertifiedKeyPair, certOrEncCert), 33 CMMFCertOrEncCertTemplate }, 34 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 0, 35 offsetof(CMMFCertifiedKeyPair, privateKey), 36 CRMFEncryptedValueTemplate }, 37 { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 38 SEC_ASN1_XTRN | 1, 39 offsetof(CMMFCertifiedKeyPair, derPublicationInfo), 40 SEC_ASN1_SUB(SEC_AnyTemplate) }, 41 { 0 } 42 }; 43 44 const SEC_ASN1Template CMMFPKIStatusInfoTemplate[] = { 45 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFPKIStatusInfo) }, 46 { SEC_ASN1_INTEGER, offsetof(CMMFPKIStatusInfo, status) }, 47 { SEC_ASN1_OPTIONAL | SEC_ASN1_UTF8_STRING, 48 offsetof(CMMFPKIStatusInfo, statusString) }, 49 { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING, 50 offsetof(CMMFPKIStatusInfo, failInfo) }, 51 { 0 } 52 }; 53 54 const SEC_ASN1Template CMMFSequenceOfCertsTemplate[] = { 55 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, 56 SEC_ASN1_SUB(SEC_SignedCertificateTemplate) } 57 }; 58 59 const SEC_ASN1Template CMMFRandTemplate[] = { 60 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFRand) }, 61 { SEC_ASN1_INTEGER, offsetof(CMMFRand, integer) }, 62 { SEC_ASN1_OCTET_STRING, offsetof(CMMFRand, senderHash) }, 63 { 0 } 64 }; 65 66 const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[] = { 67 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 68 offsetof(CMMFPOPODecKeyRespContent, responses), 69 SEC_ASN1_SUB(SEC_IntegerTemplate), 70 sizeof(CMMFPOPODecKeyRespContent) }, 71 { 0 } 72 }; 73 74 const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = { 75 { SEC_ASN1_CONTEXT_SPECIFIC | 1, 76 0, 77 CRMFEncryptedValueTemplate }, 78 { 0 } 79 }; 80 81 const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = { 82 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 83 0, 84 SEC_ASN1_SUB(SEC_SignedCertificateTemplate) }, 85 { 0 } 86 }; 87 88 const SEC_ASN1Template CMMFCertRepContentTemplate[] = { 89 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent) }, 90 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL | 91 SEC_ASN1_CONTEXT_SPECIFIC | 1, 92 offsetof(CMMFCertRepContent, caPubs), 93 CMMFSequenceOfCertsTemplate }, 94 { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response), 95 CMMFCertResponseTemplate }, 96 { 0 } 97 }; 98 99 static const SEC_ASN1Template CMMFChallengeTemplate[] = { 100 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge) }, 101 { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN, 102 offsetof(CMMFChallenge, owf), 103 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 104 { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, witness) }, 105 { SEC_ASN1_ANY, offsetof(CMMFChallenge, senderDER) }, 106 { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, key) }, 107 { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, challenge) }, 108 { 0 } 109 }; 110 111 const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = { 112 { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFPOPODecKeyChallContent, challenges), 113 CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) }, 114 { 0 } 115 }; 116 117 SECStatus 118 cmmf_decode_process_cert_response(PLArenaPool *poolp, 119 CERTCertDBHandle *db, 120 CMMFCertResponse *inCertResp) 121 { 122 SECStatus rv = SECSuccess; 123 124 if (inCertResp->certifiedKeyPair != NULL) { 125 rv = cmmf_decode_process_certified_key_pair(poolp, 126 db, 127 inCertResp->certifiedKeyPair); 128 } 129 return rv; 130 } 131 132 static CERTCertificate * 133 cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert) 134 { 135 CERTCertificate *newCert; 136 137 newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE); 138 return newCert; 139 } 140 141 static CMMFCertOrEncCertChoice 142 cmmf_get_certorenccertchoice_from_der(SECItem *der) 143 { 144 CMMFCertOrEncCertChoice retChoice; 145 146 switch (der->data[0] & 0x0f) { 147 case 0: 148 retChoice = cmmfCertificate; 149 break; 150 case 1: 151 retChoice = cmmfEncryptedCert; 152 break; 153 default: 154 retChoice = cmmfNoCertOrEncCert; 155 break; 156 } 157 return retChoice; 158 } 159 160 static SECStatus 161 cmmf_decode_process_certorenccert(PLArenaPool *poolp, 162 CERTCertDBHandle *db, 163 CMMFCertOrEncCert *inCertOrEncCert) 164 { 165 SECStatus rv = SECSuccess; 166 167 inCertOrEncCert->choice = 168 cmmf_get_certorenccertchoice_from_der(&inCertOrEncCert->derValue); 169 170 switch (inCertOrEncCert->choice) { 171 case cmmfCertificate: { 172 /* The DER has implicit tagging, so we gotta switch it to 173 * un-tagged in order for the ASN1 parser to understand it. 174 * Saving the bits that were changed. 175 */ 176 inCertOrEncCert->derValue.data[0] = 0x30; 177 inCertOrEncCert->cert.certificate = 178 cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue); 179 if (inCertOrEncCert->cert.certificate == NULL) { 180 rv = SECFailure; 181 } 182 183 } break; 184 case cmmfEncryptedCert: 185 PORT_Assert(poolp); 186 if (!poolp) { 187 PORT_SetError(SEC_ERROR_INVALID_ARGS); 188 rv = SECFailure; 189 break; 190 } 191 inCertOrEncCert->cert.encryptedCert = 192 PORT_ArenaZNew(poolp, CRMFEncryptedValue); 193 if (inCertOrEncCert->cert.encryptedCert == NULL) { 194 rv = SECFailure; 195 break; 196 } 197 rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert, 198 CMMFCertOrEncCertEncryptedCertTemplate, 199 (const char *)inCertOrEncCert->derValue.data, 200 inCertOrEncCert->derValue.len); 201 break; 202 default: 203 rv = SECFailure; 204 } 205 return rv; 206 } 207 208 SECStatus 209 cmmf_decode_process_certified_key_pair(PLArenaPool *poolp, 210 CERTCertDBHandle *db, 211 CMMFCertifiedKeyPair *inCertKeyPair) 212 { 213 return cmmf_decode_process_certorenccert(poolp, 214 db, 215 &inCertKeyPair->certOrEncCert); 216 }