security/nss/lib/crmf/asn1cmn.c

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:05b48661bf3f
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 {
173 /* The DER has implicit tagging, so we gotta switch it to
174 * un-tagged in order for the ASN1 parser to understand it.
175 * Saving the bits that were changed.
176 */
177 inCertOrEncCert->derValue.data[0] = 0x30;
178 inCertOrEncCert->cert.certificate =
179 cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue);
180 if (inCertOrEncCert->cert.certificate == NULL) {
181 rv = SECFailure;
182 }
183
184 }
185 break;
186 case cmmfEncryptedCert:
187 PORT_Assert(poolp);
188 if (!poolp) {
189 PORT_SetError(SEC_ERROR_INVALID_ARGS);
190 rv = SECFailure;
191 break;
192 }
193 inCertOrEncCert->cert.encryptedCert =
194 PORT_ArenaZNew(poolp, CRMFEncryptedValue);
195 if (inCertOrEncCert->cert.encryptedCert == NULL) {
196 rv = SECFailure;
197 break;
198 }
199 rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert,
200 CMMFCertOrEncCertEncryptedCertTemplate,
201 (const char*)inCertOrEncCert->derValue.data,
202 inCertOrEncCert->derValue.len);
203 break;
204 default:
205 rv = SECFailure;
206 }
207 return rv;
208 }
209
210 SECStatus
211 cmmf_decode_process_certified_key_pair(PLArenaPool *poolp,
212 CERTCertDBHandle *db,
213 CMMFCertifiedKeyPair *inCertKeyPair)
214 {
215 return cmmf_decode_process_certorenccert (poolp,
216 db,
217 &inCertKeyPair->certOrEncCert);
218 }
219
220

mercurial