1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/crmf/asn1cmn.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,220 @@ 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 +#include "cmmf.h" 1.9 +#include "cmmfi.h" 1.10 + 1.11 +SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 1.12 +SEC_ASN1_MKSUB(SEC_AnyTemplate) 1.13 +SEC_ASN1_MKSUB(SEC_IntegerTemplate) 1.14 +SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate) 1.15 + 1.16 +static const SEC_ASN1Template CMMFCertResponseTemplate[] = { 1.17 + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertResponse)}, 1.18 + { SEC_ASN1_INTEGER, offsetof(CMMFCertResponse, certReqId)}, 1.19 + { SEC_ASN1_INLINE, offsetof(CMMFCertResponse, status), 1.20 + CMMFPKIStatusInfoTemplate}, 1.21 + { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER, 1.22 + offsetof(CMMFCertResponse, certifiedKeyPair), 1.23 + CMMFCertifiedKeyPairTemplate}, 1.24 + { 0 } 1.25 +}; 1.26 + 1.27 +static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = { 1.28 + { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL, 1.29 + sizeof(CMMFCertOrEncCert)}, 1.30 + { 0 } 1.31 +}; 1.32 + 1.33 +const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = { 1.34 + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair)}, 1.35 + { SEC_ASN1_INLINE, offsetof(CMMFCertifiedKeyPair, certOrEncCert), 1.36 + CMMFCertOrEncCertTemplate }, 1.37 + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 0, 1.38 + offsetof(CMMFCertifiedKeyPair, privateKey), 1.39 + CRMFEncryptedValueTemplate}, 1.40 + { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1.41 + SEC_ASN1_XTRN | 1, 1.42 + offsetof (CMMFCertifiedKeyPair, derPublicationInfo), 1.43 + SEC_ASN1_SUB(SEC_AnyTemplate) }, 1.44 + { 0 } 1.45 +}; 1.46 + 1.47 +const SEC_ASN1Template CMMFPKIStatusInfoTemplate[] = { 1.48 + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFPKIStatusInfo)}, 1.49 + { SEC_ASN1_INTEGER, offsetof(CMMFPKIStatusInfo, status)}, 1.50 + { SEC_ASN1_OPTIONAL | SEC_ASN1_UTF8_STRING, 1.51 + offsetof(CMMFPKIStatusInfo, statusString)}, 1.52 + { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING, 1.53 + offsetof(CMMFPKIStatusInfo, failInfo)}, 1.54 + { 0 } 1.55 +}; 1.56 + 1.57 +const SEC_ASN1Template CMMFSequenceOfCertsTemplate[] = { 1.58 + { SEC_ASN1_SEQUENCE_OF| SEC_ASN1_XTRN, 0, 1.59 + SEC_ASN1_SUB(SEC_SignedCertificateTemplate)} 1.60 +}; 1.61 + 1.62 +const SEC_ASN1Template CMMFRandTemplate[] = { 1.63 + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFRand)}, 1.64 + { SEC_ASN1_INTEGER, offsetof(CMMFRand, integer)}, 1.65 + { SEC_ASN1_OCTET_STRING, offsetof(CMMFRand, senderHash)}, 1.66 + { 0 } 1.67 +}; 1.68 + 1.69 +const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[] = { 1.70 + { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 1.71 + offsetof(CMMFPOPODecKeyRespContent, responses), 1.72 + SEC_ASN1_SUB(SEC_IntegerTemplate), 1.73 + sizeof(CMMFPOPODecKeyRespContent)}, 1.74 + { 0 } 1.75 +}; 1.76 + 1.77 +const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = { 1.78 + { SEC_ASN1_CONTEXT_SPECIFIC | 1, 1.79 + 0, 1.80 + CRMFEncryptedValueTemplate}, 1.81 + { 0 } 1.82 +}; 1.83 + 1.84 +const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = { 1.85 + { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1.86 + 0, 1.87 + SEC_ASN1_SUB(SEC_SignedCertificateTemplate)}, 1.88 + { 0 } 1.89 +}; 1.90 + 1.91 +const SEC_ASN1Template CMMFCertRepContentTemplate[] = { 1.92 + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent)}, 1.93 + { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL | 1.94 + SEC_ASN1_CONTEXT_SPECIFIC | 1, 1.95 + offsetof(CMMFCertRepContent, caPubs), 1.96 + CMMFSequenceOfCertsTemplate }, 1.97 + { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response), 1.98 + CMMFCertResponseTemplate}, 1.99 + { 0 } 1.100 +}; 1.101 + 1.102 +static const SEC_ASN1Template CMMFChallengeTemplate[] = { 1.103 + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge)}, 1.104 + { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN, 1.105 + offsetof(CMMFChallenge, owf), 1.106 + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 1.107 + { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, witness) }, 1.108 + { SEC_ASN1_ANY, offsetof(CMMFChallenge, senderDER) }, 1.109 + { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, key) }, 1.110 + { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, challenge) }, 1.111 + { 0 } 1.112 +}; 1.113 + 1.114 +const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = { 1.115 + { SEC_ASN1_SEQUENCE_OF,offsetof(CMMFPOPODecKeyChallContent, challenges), 1.116 + CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) }, 1.117 + { 0 } 1.118 +}; 1.119 + 1.120 +SECStatus 1.121 +cmmf_decode_process_cert_response(PLArenaPool *poolp, 1.122 + CERTCertDBHandle *db, 1.123 + CMMFCertResponse *inCertResp) 1.124 +{ 1.125 + SECStatus rv = SECSuccess; 1.126 + 1.127 + if (inCertResp->certifiedKeyPair != NULL) { 1.128 + rv = cmmf_decode_process_certified_key_pair(poolp, 1.129 + db, 1.130 + inCertResp->certifiedKeyPair); 1.131 + } 1.132 + return rv; 1.133 +} 1.134 + 1.135 +static CERTCertificate* 1.136 +cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert) 1.137 +{ 1.138 + CERTCertificate *newCert; 1.139 + 1.140 + newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE); 1.141 + return newCert; 1.142 +} 1.143 + 1.144 +static CMMFCertOrEncCertChoice 1.145 +cmmf_get_certorenccertchoice_from_der(SECItem *der) 1.146 +{ 1.147 + CMMFCertOrEncCertChoice retChoice; 1.148 + 1.149 + switch(der->data[0] & 0x0f) { 1.150 + case 0: 1.151 + retChoice = cmmfCertificate; 1.152 + break; 1.153 + case 1: 1.154 + retChoice = cmmfEncryptedCert; 1.155 + break; 1.156 + default: 1.157 + retChoice = cmmfNoCertOrEncCert; 1.158 + break; 1.159 + } 1.160 + return retChoice; 1.161 +} 1.162 + 1.163 +static SECStatus 1.164 +cmmf_decode_process_certorenccert(PLArenaPool *poolp, 1.165 + CERTCertDBHandle *db, 1.166 + CMMFCertOrEncCert *inCertOrEncCert) 1.167 +{ 1.168 + SECStatus rv = SECSuccess; 1.169 + 1.170 + inCertOrEncCert->choice = 1.171 + cmmf_get_certorenccertchoice_from_der(&inCertOrEncCert->derValue); 1.172 + 1.173 + switch (inCertOrEncCert->choice) { 1.174 + case cmmfCertificate: 1.175 + { 1.176 + /* The DER has implicit tagging, so we gotta switch it to 1.177 + * un-tagged in order for the ASN1 parser to understand it. 1.178 + * Saving the bits that were changed. 1.179 + */ 1.180 + inCertOrEncCert->derValue.data[0] = 0x30; 1.181 + inCertOrEncCert->cert.certificate = 1.182 + cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue); 1.183 + if (inCertOrEncCert->cert.certificate == NULL) { 1.184 + rv = SECFailure; 1.185 + } 1.186 + 1.187 + } 1.188 + break; 1.189 + case cmmfEncryptedCert: 1.190 + PORT_Assert(poolp); 1.191 + if (!poolp) { 1.192 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.193 + rv = SECFailure; 1.194 + break; 1.195 + } 1.196 + inCertOrEncCert->cert.encryptedCert = 1.197 + PORT_ArenaZNew(poolp, CRMFEncryptedValue); 1.198 + if (inCertOrEncCert->cert.encryptedCert == NULL) { 1.199 + rv = SECFailure; 1.200 + break; 1.201 + } 1.202 + rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert, 1.203 + CMMFCertOrEncCertEncryptedCertTemplate, 1.204 + (const char*)inCertOrEncCert->derValue.data, 1.205 + inCertOrEncCert->derValue.len); 1.206 + break; 1.207 + default: 1.208 + rv = SECFailure; 1.209 + } 1.210 + return rv; 1.211 +} 1.212 + 1.213 +SECStatus 1.214 +cmmf_decode_process_certified_key_pair(PLArenaPool *poolp, 1.215 + CERTCertDBHandle *db, 1.216 + CMMFCertifiedKeyPair *inCertKeyPair) 1.217 +{ 1.218 + return cmmf_decode_process_certorenccert (poolp, 1.219 + db, 1.220 + &inCertKeyPair->certOrEncCert); 1.221 +} 1.222 + 1.223 +