security/nss/lib/crmf/asn1cmn.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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

mercurial