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