Chromium Code Reviews

Side by Side Diff: nss/lib/cryptohi/secvfy.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
1 /* 1 /*
2 * Verification stuff. 2 * Verification stuff.
3 * 3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public 4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 7
8 #include <stdio.h> 8 #include <stdio.h>
9 #include "cryptohi.h" 9 #include "cryptohi.h"
10 #include "sechash.h" 10 #include "sechash.h"
(...skipping 17 matching lines...)
28 ** Store the DigestInfo length into digestInfoLen. 28 ** Store the DigestInfo length into digestInfoLen.
29 ** 29 **
30 ** This function does *not* verify that the AlgorithmIdentifier in the 30 ** This function does *not* verify that the AlgorithmIdentifier in the
31 ** DigestInfo identifies givenDigestAlg or that the DigestInfo is encoded 31 ** DigestInfo identifies givenDigestAlg or that the DigestInfo is encoded
32 ** correctly; verifyPKCS1DigestInfo does that. 32 ** correctly; verifyPKCS1DigestInfo does that.
33 ** 33 **
34 ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION 34 ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION
35 */ 35 */
36 static SECStatus 36 static SECStatus
37 recoverPKCS1DigestInfo(SECOidTag givenDigestAlg, 37 recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
38 /*out*/ SECOidTag* digestAlgOut, 38 /*out*/ SECOidTag *digestAlgOut,
39 /*out*/ unsigned char** digestInfo, 39 /*out*/ unsigned char **digestInfo,
40 /*out*/ unsigned int* digestInfoLen, 40 /*out*/ unsigned int *digestInfoLen,
41 SECKEYPublicKey* key, 41 SECKEYPublicKey *key,
42 const SECItem* sig, void* wincx) 42 const SECItem *sig, void *wincx)
43 { 43 {
44 SGNDigestInfo* di = NULL; 44 SGNDigestInfo *di = NULL;
45 SECItem it; 45 SECItem it;
46 PRBool rv = SECSuccess; 46 PRBool rv = SECSuccess;
47 47
48 PORT_Assert(digestAlgOut); 48 PORT_Assert(digestAlgOut);
49 PORT_Assert(digestInfo); 49 PORT_Assert(digestInfo);
50 PORT_Assert(digestInfoLen); 50 PORT_Assert(digestInfoLen);
51 PORT_Assert(key); 51 PORT_Assert(key);
52 PORT_Assert(key->keyType == rsaKey); 52 PORT_Assert(key->keyType == rsaKey);
53 PORT_Assert(sig); 53 PORT_Assert(sig);
54 54
55 it.data = NULL; 55 it.data = NULL;
56 it.len = SECKEY_PublicKeyStrength(key); 56 it.len = SECKEY_PublicKeyStrength(key);
57 if (it.len != 0) { 57 if (it.len != 0) {
58 it.data = (unsigned char *)PORT_Alloc(it.len); 58 it.data = (unsigned char *)PORT_Alloc(it.len);
59 } 59 }
60 if (it.len == 0 || it.data == NULL ) { 60 if (it.len == 0 || it.data == NULL) {
61 rv = SECFailure; 61 rv = SECFailure;
62 } 62 }
63 63
64 if (rv == SECSuccess) { 64 if (rv == SECSuccess) {
65 /* decrypt the block */ 65 /* decrypt the block */
66 rv = PK11_VerifyRecover(key, sig, &it, wincx); 66 rv = PK11_VerifyRecover(key, sig, &it, wincx);
67 } 67 }
68 68
69 if (rv == SECSuccess) { 69 if (rv == SECSuccess) {
70 if (givenDigestAlg != SEC_OID_UNKNOWN) { 70 if (givenDigestAlg != SEC_OID_UNKNOWN) {
71 /* We don't need to parse the DigestInfo if the caller gave us the 71 /* We don't need to parse the DigestInfo if the caller gave us the
72 * digest algorithm to use. Later verifyPKCS1DigestInfo will verify 72 * digest algorithm to use. Later verifyPKCS1DigestInfo will verify
73 * that the DigestInfo identifies the given digest algorithm and 73 * that the DigestInfo identifies the given digest algorithm and
74 * that the DigestInfo is encoded absolutely correctly. 74 * that the DigestInfo is encoded absolutely correctly.
75 */ 75 */
76 *digestInfoLen = it.len; 76 *digestInfoLen = it.len;
77 *digestInfo = (unsigned char*)it.data; 77 *digestInfo = (unsigned char *)it.data;
78 *digestAlgOut = givenDigestAlg; 78 *digestAlgOut = givenDigestAlg;
79 return SECSuccess; 79 return SECSuccess;
80 } 80 }
81 } 81 }
82 82
83 if (rv == SECSuccess) { 83 if (rv == SECSuccess) {
84 /* The caller didn't specify a digest algorithm to use, so choose the 84 /* The caller didn't specify a digest algorithm to use, so choose the
85 * digest algorithm by parsing the AlgorithmIdentifier within the 85 * digest algorithm by parsing the AlgorithmIdentifier within the
86 * DigestInfo. 86 * DigestInfo.
87 */ 87 */
88 di = SGN_DecodeDigestInfo(&it); 88 di = SGN_DecodeDigestInfo(&it);
89 if (!di) { 89 if (!di) {
90 rv = SECFailure; 90 rv = SECFailure;
91 } 91 }
92 } 92 }
93 93
94 if (rv == SECSuccess) { 94 if (rv == SECSuccess) {
95 *digestAlgOut = SECOID_GetAlgorithmTag(&di->digestAlgorithm); 95 *digestAlgOut = SECOID_GetAlgorithmTag(&di->digestAlgorithm);
96 if (*digestAlgOut == SEC_OID_UNKNOWN) { 96 if (*digestAlgOut == SEC_OID_UNKNOWN) {
97 rv = SECFailure; 97 rv = SECFailure;
98 } 98 }
99 } 99 }
100 100
101 if (di) { 101 if (di) {
102 SGN_DestroyDigestInfo(di); 102 SGN_DestroyDigestInfo(di);
103 } 103 }
104 104
105 if (rv == SECSuccess) { 105 if (rv == SECSuccess) {
106 *digestInfoLen = it.len; 106 *digestInfoLen = it.len;
107 *digestInfo = (unsigned char*)it.data; 107 *digestInfo = (unsigned char *)it.data;
108 } else { 108 } else {
109 if (it.data) { 109 if (it.data) {
110 PORT_Free(it.data); 110 PORT_Free(it.data);
111 } 111 }
112 *digestInfo = NULL; 112 *digestInfo = NULL;
113 *digestInfoLen = 0; 113 *digestInfoLen = 0;
114 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 114 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
115 } 115 }
116 116
117 return rv; 117 return rv;
118 } 118 }
119 119
120 struct VFYContextStr { 120 struct VFYContextStr {
121 SECOidTag hashAlg; /* the hash algorithm */ 121 SECOidTag hashAlg; /* the hash algorithm */
122 SECKEYPublicKey *key; 122 SECKEYPublicKey *key;
123 /* 123 /*
124 * This buffer holds either the digest or the full signature 124 * This buffer holds either the digest or the full signature
125 * depending on the type of the signature (key->keyType). It is 125 * depending on the type of the signature (key->keyType). It is
126 * defined as a union to make sure it always has enough space. 126 * defined as a union to make sure it always has enough space.
127 * 127 *
128 * Use the "buffer" union member to reference the buffer. 128 * Use the "buffer" union member to reference the buffer.
129 * Note: do not take the size of the "buffer" union member. Take 129 * Note: do not take the size of the "buffer" union member. Take
130 * the size of the union or some other union member instead. 130 * the size of the union or some other union member instead.
131 */ 131 */
132 union { 132 union {
133 » unsigned char buffer[1]; 133 unsigned char buffer[1];
134 134
135 » /* the full DSA signature... 40 bytes */ 135 /* the full DSA signature... 40 bytes */
136 » unsigned char dsasig[DSA_MAX_SIGNATURE_LEN]; 136 unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
137 » /* the full ECDSA signature */ 137 /* the full ECDSA signature */
138 » unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; 138 unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
139 } u; 139 } u;
140 unsigned int pkcs1RSADigestInfoLen; 140 unsigned int pkcs1RSADigestInfoLen;
141 /* the encoded DigestInfo from a RSA PKCS#1 signature */ 141 /* the encoded DigestInfo from a RSA PKCS#1 signature */
142 unsigned char *pkcs1RSADigestInfo; 142 unsigned char *pkcs1RSADigestInfo;
143 void * wincx; 143 void *wincx;
144 void *hashcx; 144 void *hashcx;
145 const SECHashObject *hashobj; 145 const SECHashObject *hashobj;
146 SECOidTag encAlg; /* enc alg */ 146 SECOidTag encAlg; /* enc alg */
147 PRBool hasSignature; /* true if the signature was provided in the 147 PRBool hasSignature; /* true if the signature was provided in the
148 * VFY_CreateContext call. If false, the 148 * VFY_CreateContext call. If false, the
149 * signature must be provided with a 149 * signature must be provided with a
150 * VFY_EndWithSignature call. */ 150 * VFY_EndWithSignature call. */
151 }; 151 };
152 152
153 static SECStatus 153 static SECStatus
154 verifyPKCS1DigestInfo(const VFYContext* cx, const SECItem* digest) 154 verifyPKCS1DigestInfo(const VFYContext *cx, const SECItem *digest)
155 { 155 {
156 SECItem pkcs1DigestInfo; 156 SECItem pkcs1DigestInfo;
157 pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo; 157 pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo;
158 pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen; 158 pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen;
159 return _SGN_VerifyPKCS1DigestInfo( 159 return _SGN_VerifyPKCS1DigestInfo(
160 cx->hashAlg, digest, &pkcs1DigestInfo, 160 cx->hashAlg, digest, &pkcs1DigestInfo,
161 PR_TRUE /*XXX: unsafeAllowMissingParameters*/); 161 PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
162 } 162 }
163 163
164 /* 164 /*
165 * decode the ECDSA or DSA signature from it's DER wrapping. 165 * decode the ECDSA or DSA signature from it's DER wrapping.
166 * The unwrapped/raw signature is placed in the buffer pointed 166 * The unwrapped/raw signature is placed in the buffer pointed
167 * to by dsig and has enough room for len bytes. 167 * to by dsig and has enough room for len bytes.
168 */ 168 */
169 static SECStatus 169 static SECStatus
170 decodeECorDSASignature(SECOidTag algid, const SECItem *sig, unsigned char *dsig, 170 decodeECorDSASignature(SECOidTag algid, const SECItem *sig, unsigned char *dsig,
171 » » unsigned int len) { 171 unsigned int len)
172 {
172 SECItem *dsasig = NULL; /* also used for ECDSA */ 173 SECItem *dsasig = NULL; /* also used for ECDSA */
173 SECStatus rv=SECSuccess; 174 SECStatus rv = SECSuccess;
174 175
175 if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) && 176 if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
176 » (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) { 177 (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
177 if (sig->len != len) { 178 if (sig->len != len) {
178 » PORT_SetError(SEC_ERROR_BAD_DER); 179 PORT_SetError(SEC_ERROR_BAD_DER);
179 » return SECFailure; 180 return SECFailure;
180 » } 181 }
181 182
182 » PORT_Memcpy(dsig, sig->data, sig->len); 183 PORT_Memcpy(dsig, sig->data, sig->len);
183 » return SECSuccess; 184 return SECSuccess;
184 } 185 }
185 186
186 if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { 187 if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
187 » if (len > MAX_ECKEY_LEN * 2) { 188 if (len > MAX_ECKEY_LEN * 2) {
188 » PORT_SetError(SEC_ERROR_BAD_DER); 189 PORT_SetError(SEC_ERROR_BAD_DER);
189 » return SECFailure; 190 return SECFailure;
190 » } 191 }
191 } 192 }
192 dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); 193 dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len);
193 194
194 if ((dsasig == NULL) || (dsasig->len != len)) { 195 if ((dsasig == NULL) || (dsasig->len != len)) {
195 » rv = SECFailure; 196 rv = SECFailure;
196 } else { 197 } else {
197 » PORT_Memcpy(dsig, dsasig->data, dsasig->len); 198 PORT_Memcpy(dsig, dsasig->data, dsasig->len);
198 } 199 }
199 200
200 if (dsasig != NULL) SECITEM_FreeItem(dsasig, PR_TRUE); 201 if (dsasig != NULL)
201 if (rv == SECFailure) PORT_SetError(SEC_ERROR_BAD_DER); 202 SECITEM_FreeItem(dsasig, PR_TRUE);
203 if (rv == SECFailure)
204 PORT_SetError(SEC_ERROR_BAD_DER);
202 return rv; 205 return rv;
203 } 206 }
204 207
205 const SEC_ASN1Template hashParameterTemplate[] = 208 const SEC_ASN1Template hashParameterTemplate[] =
206 { 209 {
207 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) }, 210 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
208 { SEC_ASN1_OBJECT_ID, 0 }, 211 { SEC_ASN1_OBJECT_ID, 0 },
209 { SEC_ASN1_SKIP_REST }, 212 { SEC_ASN1_SKIP_REST },
210 { 0, } 213 { 0 }
211 }; 214 };
212 215
213 /* 216 /*
214 * Pulls the hash algorithm, signing algorithm, and key type out of a 217 * Pulls the hash algorithm, signing algorithm, and key type out of a
215 * composite algorithm. 218 * composite algorithm.
216 * 219 *
217 * sigAlg: the composite algorithm to dissect. 220 * sigAlg: the composite algorithm to dissect.
218 * hashalg: address of a SECOidTag which will be set with the hash algorithm. 221 * hashalg: address of a SECOidTag which will be set with the hash algorithm.
219 * encalg: address of a SECOidTag which will be set with the signing alg. 222 * encalg: address of a SECOidTag which will be set with the signing alg.
220 * 223 *
221 * Returns: SECSuccess if the algorithm was acceptable, SECFailure if the 224 * Returns: SECSuccess if the algorithm was acceptable, SECFailure if the
222 * algorithm was not found or was not a signing algorithm. 225 * algorithm was not found or was not a signing algorithm.
223 */ 226 */
224 SECStatus 227 SECStatus
225 sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, 228 sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
226 const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg) 229 const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg)
227 { 230 {
228 int len; 231 int len;
229 PLArenaPool *arena; 232 PLArenaPool *arena;
230 SECStatus rv; 233 SECStatus rv;
231 SECItem oid; 234 SECItem oid;
232 235
233 PR_ASSERT(hashalg!=NULL); 236 PR_ASSERT(hashalg != NULL);
234 PR_ASSERT(encalg!=NULL); 237 PR_ASSERT(encalg != NULL);
235 238
236 switch (sigAlg) { 239 switch (sigAlg) {
237 /* We probably shouldn't be generating MD2 signatures either */ 240 /* We probably shouldn't be generating MD2 signatures either */
238 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: 241 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
239 *hashalg = SEC_OID_MD2; 242 *hashalg = SEC_OID_MD2;
240 » break; 243 break;
241 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: 244 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
242 *hashalg = SEC_OID_MD5; 245 *hashalg = SEC_OID_MD5;
243 » break; 246 break;
244 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: 247 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
245 case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: 248 case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
246 case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: 249 case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
247 *hashalg = SEC_OID_SHA1; 250 *hashalg = SEC_OID_SHA1;
248 » break; 251 break;
249 case SEC_OID_PKCS1_RSA_ENCRYPTION: 252 case SEC_OID_PKCS1_RSA_ENCRYPTION:
250 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: 253 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
251 *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */ 254 *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
252 » break; 255 break;
253 256
254 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: 257 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
255 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: 258 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
256 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: 259 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
257 » *hashalg = SEC_OID_SHA224; 260 *hashalg = SEC_OID_SHA224;
258 » break; 261 break;
259 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: 262 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
260 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: 263 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
261 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: 264 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
262 » *hashalg = SEC_OID_SHA256; 265 *hashalg = SEC_OID_SHA256;
263 » break; 266 break;
264 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: 267 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
265 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: 268 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
266 » *hashalg = SEC_OID_SHA384; 269 *hashalg = SEC_OID_SHA384;
267 » break; 270 break;
268 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: 271 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
269 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: 272 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
270 » *hashalg = SEC_OID_SHA512; 273 *hashalg = SEC_OID_SHA512;
271 » break; 274 break;
272 275
273 /* what about normal DSA? */ 276 /* what about normal DSA? */
274 case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: 277 case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
275 case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: 278 case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
276 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: 279 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
277 *hashalg = SEC_OID_SHA1; 280 *hashalg = SEC_OID_SHA1;
278 » break; 281 break;
279 case SEC_OID_MISSI_DSS: 282 case SEC_OID_MISSI_DSS:
280 case SEC_OID_MISSI_KEA_DSS: 283 case SEC_OID_MISSI_KEA_DSS:
281 case SEC_OID_MISSI_KEA_DSS_OLD: 284 case SEC_OID_MISSI_KEA_DSS_OLD:
282 case SEC_OID_MISSI_DSS_OLD: 285 case SEC_OID_MISSI_DSS_OLD:
283 *hashalg = SEC_OID_SHA1; 286 *hashalg = SEC_OID_SHA1;
284 » break; 287 break;
285 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: 288 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
286 » /* This is an EC algorithm. Recommended means the largest 289 /* This is an EC algorithm. Recommended means the largest
287 » * hash algorithm that is not reduced by the keysize of 290 * hash algorithm that is not reduced by the keysize of
288 » * the EC algorithm. Note that key strength is in bytes and 291 * the EC algorithm. Note that key strength is in bytes and
289 » * algorithms are specified in bits. Never use an algorithm 292 * algorithms are specified in bits. Never use an algorithm
290 » * weaker than sha1. */ 293 * weaker than sha1. */
291 » len = SECKEY_PublicKeyStrength(key); 294 len = SECKEY_PublicKeyStrength(key);
292 » if (len < 28) { /* 28 bytes == 224 bits */ 295 if (len < 28) { /* 28 bytes == 224 bits */
293 » *hashalg = SEC_OID_SHA1; 296 *hashalg = SEC_OID_SHA1;
294 » } else if (len < 32) { /* 32 bytes == 256 bits */ 297 } else if (len < 32) { /* 32 bytes == 256 bits */
295 » *hashalg = SEC_OID_SHA224; 298 *hashalg = SEC_OID_SHA224;
296 » } else if (len < 48) { /* 48 bytes == 384 bits */ 299 } else if (len < 48) { /* 48 bytes == 384 bits */
297 » *hashalg = SEC_OID_SHA256; 300 *hashalg = SEC_OID_SHA256;
298 » } else if (len < 64) { /* 48 bytes == 512 bits */ 301 } else if (len < 64) { /* 48 bytes == 512 bits */
299 » *hashalg = SEC_OID_SHA384; 302 *hashalg = SEC_OID_SHA384;
300 » } else { 303 } else {
301 » /* use the largest in this case */ 304 /* use the largest in this case */
302 » *hashalg = SEC_OID_SHA512; 305 *hashalg = SEC_OID_SHA512;
303 » } 306 }
304 » break; 307 break;
305 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: 308 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
306 » if (param == NULL) { 309 if (param == NULL) {
307 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 310 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
308 » return SECFailure; 311 return SECFailure;
309 » } 312 }
310 » arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 313 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
311 » if (arena == NULL) { 314 if (arena == NULL) {
312 » return SECFailure; 315 return SECFailure;
313 » } 316 }
314 » rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, param); 317 rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, para m);
315 » if (rv == SECSuccess) { 318 if (rv == SECSuccess) {
316 *hashalg = SECOID_FindOIDTag(&oid); 319 *hashalg = SECOID_FindOIDTag(&oid);
317 } 320 }
318 PORT_FreeArena(arena, PR_FALSE); 321 PORT_FreeArena(arena, PR_FALSE);
319 if (rv != SECSuccess) { 322 if (rv != SECSuccess) {
320 » return rv; 323 return rv;
321 » } 324 }
322 » /* only accept hash algorithms */ 325 /* only accept hash algorithms */
323 » if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) { 326 if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) {
324 » /* error set by HASH_GetHashTypeByOidTag */ 327 /* error set by HASH_GetHashTypeByOidTag */
325 » return SECFailure; 328 return SECFailure;
326 » } 329 }
327 » break; 330 break;
328 /* we don't implement MD4 hashes */ 331 /* we don't implement MD4 hashes */
329 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: 332 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
330 default: 333 default:
331 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 334 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
332 » return SECFailure; 335 return SECFailure;
333 } 336 }
334 /* get the "encryption" algorithm */ 337 /* get the "encryption" algorithm */
335 switch (sigAlg) { 338 switch (sigAlg) {
336 case SEC_OID_PKCS1_RSA_ENCRYPTION: 339 case SEC_OID_PKCS1_RSA_ENCRYPTION:
337 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: 340 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
338 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: 341 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
339 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: 342 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
340 case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: 343 case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
341 case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: 344 case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
342 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: 345 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
343 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: 346 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
344 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: 347 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
345 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: 348 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
346 » *encalg = SEC_OID_PKCS1_RSA_ENCRYPTION; 349 *encalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
347 » break; 350 break;
348 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: 351 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
349 » *encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE; 352 *encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
350 » break; 353 break;
351 354
352 /* what about normal DSA? */ 355 /* what about normal DSA? */
353 case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: 356 case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
354 case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: 357 case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
355 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: 358 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
356 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: 359 case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
357 » *encalg = SEC_OID_ANSIX9_DSA_SIGNATURE; 360 *encalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
358 » break; 361 break;
359 case SEC_OID_MISSI_DSS: 362 case SEC_OID_MISSI_DSS:
360 case SEC_OID_MISSI_KEA_DSS: 363 case SEC_OID_MISSI_KEA_DSS:
361 case SEC_OID_MISSI_KEA_DSS_OLD: 364 case SEC_OID_MISSI_KEA_DSS_OLD:
362 case SEC_OID_MISSI_DSS_OLD: 365 case SEC_OID_MISSI_DSS_OLD:
363 » *encalg = SEC_OID_MISSI_DSS; 366 *encalg = SEC_OID_MISSI_DSS;
364 » break; 367 break;
365 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: 368 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
366 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: 369 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
367 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: 370 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
368 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: 371 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
369 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: 372 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
370 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: 373 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
371 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: 374 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
372 » *encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; 375 *encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
373 » break; 376 break;
374 /* we don't implement MD4 hashes */ 377 /* we don't implement MD4 hashes */
375 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: 378 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
376 default: 379 default:
377 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 380 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
378 » return SECFailure; 381 return SECFailure;
379 } 382 }
380 return SECSuccess; 383 return SECSuccess;
381 } 384 }
382 385
383 /* 386 /*
384 * we can verify signatures that come from 2 different sources: 387 * we can verify signatures that come from 2 different sources:
385 * one in with the signature contains a signature oid, and the other 388 * one in with the signature contains a signature oid, and the other
386 * in which the signature is managed by a Public key (encAlg) oid 389 * in which the signature is managed by a Public key (encAlg) oid
387 * and a hash oid. The latter is the more basic, so that's what 390 * and a hash oid. The latter is the more basic, so that's what
388 * our base vfyCreate function takes. 391 * our base vfyCreate function takes.
389 * 392 *
390 * There is one noteworthy corner case, if we are using an RSA key, and the 393 * There is one noteworthy corner case, if we are using an RSA key, and the
391 * signature block is provided, then the hashAlg can be specified as 394 * signature block is provided, then the hashAlg can be specified as
392 * SEC_OID_UNKNOWN. In this case, verify will use the hash oid supplied 395 * SEC_OID_UNKNOWN. In this case, verify will use the hash oid supplied
393 * in the RSA signature block. 396 * in the RSA signature block.
394 */ 397 */
395 static VFYContext * 398 static VFYContext *
396 vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, 399 vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
397 » SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wincx) 400 SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wi ncx)
398 { 401 {
399 VFYContext *cx; 402 VFYContext *cx;
400 SECStatus rv; 403 SECStatus rv;
401 unsigned int sigLen; 404 unsigned int sigLen;
402 KeyType type; 405 KeyType type;
403 406
404 /* make sure the encryption algorithm matches the key type */ 407 /* make sure the encryption algorithm matches the key type */
405 /* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */ 408 /* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */
406 type = seckey_GetKeyType(encAlg); 409 type = seckey_GetKeyType(encAlg);
407 if ((key->keyType != type) && 410 if ((key->keyType != type) &&
408 » ((key->keyType != rsaKey) || (type != rsaPssKey))) { 411 ((key->keyType != rsaKey) || (type != rsaPssKey))) {
409 » PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH); 412 PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH);
410 » return NULL; 413 return NULL;
411 } 414 }
412 415
413 cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext)); 416 cx = (VFYContext *)PORT_ZAlloc(sizeof(VFYContext));
414 if (cx == NULL) { 417 if (cx == NULL) {
415 » goto loser; 418 goto loser;
416 } 419 }
417 420
418 cx->wincx = wincx; 421 cx->wincx = wincx;
419 cx->hasSignature = (sig != NULL); 422 cx->hasSignature = (sig != NULL);
420 cx->encAlg = encAlg; 423 cx->encAlg = encAlg;
421 cx->hashAlg = hashAlg; 424 cx->hashAlg = hashAlg;
422 cx->key = SECKEY_CopyPublicKey(key); 425 cx->key = SECKEY_CopyPublicKey(key);
423 cx->pkcs1RSADigestInfo = NULL; 426 cx->pkcs1RSADigestInfo = NULL;
424 rv = SECSuccess; 427 rv = SECSuccess;
425 if (sig) { 428 if (sig) {
426 » switch (type) { 429 switch (type) {
427 » case rsaKey: 430 case rsaKey:
428 » rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, 431 rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg,
429 » » » » » &cx->pkcs1RSADigestInfo, 432 &cx->pkcs1RSADigestInfo,
430 » » » » » &cx->pkcs1RSADigestInfoLen, 433 &cx->pkcs1RSADigestInfoLen,
431 » » » » » cx->key, 434 cx->key,
432 » » » » » sig, wincx); 435 sig, wincx);
433 » break; 436 break;
434 » case dsaKey: 437 case dsaKey:
435 » case ecKey: 438 case ecKey:
436 » sigLen = SECKEY_SignatureLen(key); 439 sigLen = SECKEY_SignatureLen(key);
437 » if (sigLen == 0) { 440 if (sigLen == 0) {
438 » » /* error set by SECKEY_SignatureLen */ 441 /* error set by SECKEY_SignatureLen */
439 » » rv = SECFailure;» 442 rv = SECFailure;
440 » » break; 443 break;
441 » } 444 }
442 » rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen); 445 rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen);
443 » break; 446 break;
444 » default: 447 default:
445 » rv = SECFailure; 448 rv = SECFailure;
446 » PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 449 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
447 » break; 450 break;
448 » } 451 }
449 } 452 }
450 453
451 if (rv) goto loser; 454 if (rv)
455 goto loser;
452 456
453 /* check hash alg again, RSA may have changed it.*/ 457 /* check hash alg again, RSA may have changed it.*/
454 if (HASH_GetHashTypeByOidTag(cx->hashAlg) == HASH_AlgNULL) { 458 if (HASH_GetHashTypeByOidTag(cx->hashAlg) == HASH_AlgNULL) {
455 » /* error set by HASH_GetHashTypeByOidTag */ 459 /* error set by HASH_GetHashTypeByOidTag */
456 » goto loser; 460 goto loser;
457 } 461 }
458 462
459 if (hash) { 463 if (hash) {
460 » *hash = cx->hashAlg; 464 *hash = cx->hashAlg;
461 } 465 }
462 return cx; 466 return cx;
463 467
464 loser: 468 loser:
465 if (cx) { 469 if (cx) {
466 » VFY_DestroyContext(cx, PR_TRUE); 470 VFY_DestroyContext(cx, PR_TRUE);
467 } 471 }
468 return 0; 472 return 0;
469 } 473 }
470 474
471 VFYContext * 475 VFYContext *
472 VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag sigAlg, 476 VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag sigAlg,
473 » » void *wincx) 477 void *wincx)
474 { 478 {
475 SECOidTag encAlg, hashAlg; 479 SECOidTag encAlg, hashAlg;
476 SECStatus rv = sec_DecodeSigAlg(key, sigAlg, NULL, &encAlg, &hashAlg); 480 SECStatus rv = sec_DecodeSigAlg(key, sigAlg, NULL, &encAlg, &hashAlg);
477 if (rv != SECSuccess) { 481 if (rv != SECSuccess) {
478 » return NULL; 482 return NULL;
479 } 483 }
480 return vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx); 484 return vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
481 } 485 }
482 486
483 VFYContext * 487 VFYContext *
484 VFY_CreateContextDirect(const SECKEYPublicKey *key, const SECItem *sig, 488 VFY_CreateContextDirect(const SECKEYPublicKey *key, const SECItem *sig,
485 » » » SECOidTag encAlg, SECOidTag hashAlg, 489 SECOidTag encAlg, SECOidTag hashAlg,
486 » » » SECOidTag *hash, void *wincx) 490 SECOidTag *hash, void *wincx)
487 { 491 {
488 return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx); 492 return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
489 } 493 }
490 494
491 VFYContext * 495 VFYContext *
492 VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig, 496 VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig,
493 » const SECAlgorithmID *sigAlgorithm, SECOidTag *hash, void *wincx) 497 const SECAlgorithmID *sigAlgorithm, SECOidTag * hash, void *wincx)
494 { 498 {
495 SECOidTag encAlg, hashAlg; 499 SECOidTag encAlg, hashAlg;
496 SECStatus rv = sec_DecodeSigAlg(key, 500 SECStatus rv = sec_DecodeSigAlg(key,
497 » » SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm), 501 SECOID_GetAlgorithmTag((SECAlgorithmID *)sig Algorithm),
498 » » &sigAlgorithm->parameters, &encAlg, &hashAlg); 502 &sigAlgorithm->parameters, &encAlg, &hashAlg );
499 if (rv != SECSuccess) { 503 if (rv != SECSuccess) {
500 » return NULL; 504 return NULL;
501 } 505 }
502 return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx); 506 return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
503 } 507 }
504 508
505 void 509 void
506 VFY_DestroyContext(VFYContext *cx, PRBool freeit) 510 VFY_DestroyContext(VFYContext *cx, PRBool freeit)
507 { 511 {
508 if (cx) { 512 if (cx) {
509 » if (cx->hashcx != NULL) { 513 if (cx->hashcx != NULL) {
510 » (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); 514 (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
511 » cx->hashcx = NULL; 515 cx->hashcx = NULL;
512 » } 516 }
513 » if (cx->key) { 517 if (cx->key) {
514 » SECKEY_DestroyPublicKey(cx->key); 518 SECKEY_DestroyPublicKey(cx->key);
515 » } 519 }
516 if (cx->pkcs1RSADigestInfo) { 520 if (cx->pkcs1RSADigestInfo) {
517 PORT_Free(cx->pkcs1RSADigestInfo); 521 PORT_Free(cx->pkcs1RSADigestInfo);
518 } 522 }
519 » if (freeit) { 523 if (freeit) {
520 » PORT_ZFree(cx, sizeof(VFYContext)); 524 PORT_ZFree(cx, sizeof(VFYContext));
521 » } 525 }
522 } 526 }
523 } 527 }
524 528
525 SECStatus 529 SECStatus
526 VFY_Begin(VFYContext *cx) 530 VFY_Begin(VFYContext *cx)
527 { 531 {
528 if (cx->hashcx != NULL) { 532 if (cx->hashcx != NULL) {
529 » (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); 533 (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
530 » cx->hashcx = NULL; 534 cx->hashcx = NULL;
531 } 535 }
532 536
533 cx->hashobj = HASH_GetHashObjectByOidTag(cx->hashAlg); 537 cx->hashobj = HASH_GetHashObjectByOidTag(cx->hashAlg);
534 if (!cx->hashobj) 538 if (!cx->hashobj)
535 » return SECFailure;» /* error code is set */ 539 return SECFailure; /* error code is set */
536 540
537 cx->hashcx = (*cx->hashobj->create)(); 541 cx->hashcx = (*cx->hashobj->create)();
538 if (cx->hashcx == NULL) 542 if (cx->hashcx == NULL)
539 » return SECFailure; 543 return SECFailure;
540 544
541 (*cx->hashobj->begin)(cx->hashcx); 545 (*cx->hashobj->begin)(cx->hashcx);
542 return SECSuccess; 546 return SECSuccess;
543 } 547 }
544 548
545 SECStatus 549 SECStatus
546 VFY_Update(VFYContext *cx, const unsigned char *input, unsigned inputLen) 550 VFY_Update(VFYContext *cx, const unsigned char *input, unsigned inputLen)
547 { 551 {
548 if (cx->hashcx == NULL) { 552 if (cx->hashcx == NULL) {
549 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 553 PORT_SetError(SEC_ERROR_INVALID_ARGS);
550 » return SECFailure; 554 return SECFailure;
551 } 555 }
552 (*cx->hashobj->update)(cx->hashcx, input, inputLen); 556 (*cx->hashobj->update)(cx->hashcx, input, inputLen);
553 return SECSuccess; 557 return SECSuccess;
554 } 558 }
555 559
556 SECStatus 560 SECStatus
557 VFY_EndWithSignature(VFYContext *cx, SECItem *sig) 561 VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
558 { 562 {
559 unsigned char final[HASH_LENGTH_MAX]; 563 unsigned char final[HASH_LENGTH_MAX];
560 unsigned part; 564 unsigned part;
561 SECItem hash,dsasig; /* dsasig is also used for ECDSA */ 565 SECItem hash, dsasig; /* dsasig is also used for ECDSA */
562 SECStatus rv; 566 SECStatus rv;
563 567
564 if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) { 568 if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) {
565 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 569 PORT_SetError(SEC_ERROR_INVALID_ARGS);
566 » return SECFailure; 570 return SECFailure;
567 } 571 }
568 572
569 if (cx->hashcx == NULL) { 573 if (cx->hashcx == NULL) {
570 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 574 PORT_SetError(SEC_ERROR_INVALID_ARGS);
571 » return SECFailure; 575 return SECFailure;
572 } 576 }
573 (*cx->hashobj->end)(cx->hashcx, final, &part, sizeof(final)); 577 (*cx->hashobj->end)(cx->hashcx, final, &part, sizeof(final));
574 switch (cx->key->keyType) { 578 switch (cx->key->keyType) {
575 case ecKey: 579 case ecKey:
576 case dsaKey: 580 case dsaKey:
577 » dsasig.data = cx->u.buffer; 581 dsasig.data = cx->u.buffer;
578 » dsasig.len = SECKEY_SignatureLen(cx->key); 582 dsasig.len = SECKEY_SignatureLen(cx->key);
579 » if (dsasig.len == 0) { 583 if (dsasig.len == 0) {
580 » return SECFailure; 584 return SECFailure;
581 » } 585 }
582 » if (sig) { 586 if (sig) {
583 » rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data, 587 rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data,
584 » » » » » dsasig.len); 588 dsasig.len);
585 » if (rv != SECSuccess) { 589 if (rv != SECSuccess) {
586 » » PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 590 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
587 » » return SECFailure; 591 return SECFailure;
588 » } 592 }
589 » } 593 }
590 » hash.data = final; 594 hash.data = final;
591 » hash.len = part; 595 hash.len = part;
592 » if (PK11_Verify(cx->key,&dsasig,&hash,cx->wincx) != SECSuccess) { 596 if (PK11_Verify(cx->key, &dsasig, &hash, cx->wincx) != SECSuccess) {
593 » » PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 597 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
594 » » return SECFailure; 598 return SECFailure;
595 » } 599 }
596 » break; 600 break;
597 case rsaKey: 601 case rsaKey: {
598 { 602 SECItem digest;
599 SECItem digest; 603 digest.data = final;
600 digest.data = final; 604 digest.len = part;
601 digest.len = part; 605 if (sig) {
602 » if (sig) { 606 SECOidTag hashid;
603 » SECOidTag hashid; 607 PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
604 » PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN); 608 rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
605 » rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid, 609 &cx->pkcs1RSADigestInfo,
606 » » » » » &cx->pkcs1RSADigestInfo, 610 &cx->pkcs1RSADigestInfoLen,
607 » » » » » &cx->pkcs1RSADigestInfoLen, 611 cx->key,
608 » » » » » cx->key, 612 sig, cx->wincx);
609 » » » » » sig, cx->wincx); 613 PORT_Assert(cx->hashAlg == hashid);
610 » PORT_Assert(cx->hashAlg == hashid); 614 if (rv != SECSuccess) {
611 » if (rv != SECSuccess) { 615 return SECFailure;
612 » » return SECFailure; 616 }
613 » } 617 }
614 » } 618 return verifyPKCS1DigestInfo(cx, &digest);
615 » return verifyPKCS1DigestInfo(cx, &digest); 619 }
616 } 620 default:
617 default: 621 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
618 » PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 622 return SECFailure; /* shouldn't happen */
619 » return SECFailure; /* shouldn't happen */
620 } 623 }
621 return SECSuccess; 624 return SECSuccess;
622 } 625 }
623 626
624 SECStatus 627 SECStatus
625 VFY_End(VFYContext *cx) 628 VFY_End(VFYContext *cx)
626 { 629 {
627 return VFY_EndWithSignature(cx,NULL); 630 return VFY_EndWithSignature(cx, NULL);
628 } 631 }
629 632
630 /************************************************************************/ 633 /************************************************************************/
631 /* 634 /*
632 * Verify that a previously-computed digest matches a signature. 635 * Verify that a previously-computed digest matches a signature.
633 */ 636 */
634 static SECStatus 637 static SECStatus
635 vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key, 638 vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key,
636 » » const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg, 639 const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
637 » » void *wincx) 640 void *wincx)
638 { 641 {
639 SECStatus rv; 642 SECStatus rv;
640 VFYContext *cx; 643 VFYContext *cx;
641 SECItem dsasig; /* also used for ECDSA */ 644 SECItem dsasig; /* also used for ECDSA */
642 645
643 rv = SECFailure; 646 rv = SECFailure;
644 647
645 cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx); 648 cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
646 if (cx != NULL) { 649 if (cx != NULL) {
647 » switch (key->keyType) { 650 switch (key->keyType) {
648 » case rsaKey: 651 case rsaKey:
649 » rv = verifyPKCS1DigestInfo(cx, digest); 652 rv = verifyPKCS1DigestInfo(cx, digest);
650 » break; 653 break;
651 » case dsaKey: 654 case dsaKey:
652 » case ecKey: 655 case ecKey:
653 » dsasig.data = cx->u.buffer; 656 dsasig.data = cx->u.buffer;
654 » dsasig.len = SECKEY_SignatureLen(cx->key); 657 dsasig.len = SECKEY_SignatureLen(cx->key);
655 » if (dsasig.len == 0) { 658 if (dsasig.len == 0) {
656 » » break; 659 break;
657 » } 660 }
658 » if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx) 661 if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx) !=
659 » » != SECSuccess) { 662 SECSuccess) {
660 » » PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 663 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
661 » } else { 664 } else {
662 » » rv = SECSuccess; 665 rv = SECSuccess;
663 » } 666 }
664 » break; 667 break;
665 » default: 668 default:
666 » break; 669 break;
667 » } 670 }
668 » VFY_DestroyContext(cx, PR_TRUE); 671 VFY_DestroyContext(cx, PR_TRUE);
669 } 672 }
670 return rv; 673 return rv;
671 } 674 }
672 675
673 SECStatus 676 SECStatus
674 VFY_VerifyDigestDirect(const SECItem *digest, const SECKEYPublicKey *key, 677 VFY_VerifyDigestDirect(const SECItem *digest, const SECKEYPublicKey *key,
675 » » const SECItem *sig, SECOidTag encAlg, 678 const SECItem *sig, SECOidTag encAlg,
676 » » SECOidTag hashAlg, void *wincx) 679 SECOidTag hashAlg, void *wincx)
677 { 680 {
678 return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx); 681 return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
679 } 682 }
680 683
681 SECStatus 684 SECStatus
682 VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, 685 VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
683 » » SECOidTag algid, void *wincx) 686 SECOidTag algid, void *wincx)
684 { 687 {
685 SECOidTag encAlg, hashAlg; 688 SECOidTag encAlg, hashAlg;
686 SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg); 689 SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
687 if (rv != SECSuccess) { 690 if (rv != SECSuccess) {
688 » return SECFailure; 691 return SECFailure;
689 } 692 }
690 return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx); 693 return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
691 } 694 }
692 695
693 /* 696 /*
694 * this function takes an optional hash oid, which the digest function 697 * this function takes an optional hash oid, which the digest function
695 * will be compared with our target hash value. 698 * will be compared with our target hash value.
696 */ 699 */
697 SECStatus 700 SECStatus
698 VFY_VerifyDigestWithAlgorithmID(const SECItem *digest, 701 VFY_VerifyDigestWithAlgorithmID(const SECItem *digest,
699 » » const SECKEYPublicKey *key, const SECItem *sig, 702 const SECKEYPublicKey *key, const SECItem *sig,
700 » » const SECAlgorithmID *sigAlgorithm, 703 const SECAlgorithmID *sigAlgorithm,
701 » » SECOidTag hashCmp, void *wincx) 704 SECOidTag hashCmp, void *wincx)
702 { 705 {
703 SECOidTag encAlg, hashAlg; 706 SECOidTag encAlg, hashAlg;
704 SECStatus rv = sec_DecodeSigAlg(key, 707 SECStatus rv = sec_DecodeSigAlg(key,
705 » » SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm), 708 SECOID_GetAlgorithmTag((SECAlgorithmID *)sig Algorithm),
706 » » &sigAlgorithm->parameters, &encAlg, &hashAlg); 709 &sigAlgorithm->parameters, &encAlg, &hashAlg );
707 if (rv != SECSuccess) { 710 if (rv != SECSuccess) {
708 » return rv; 711 return rv;
709 } 712 }
710 if ( hashCmp != SEC_OID_UNKNOWN && 713 if (hashCmp != SEC_OID_UNKNOWN &&
711 » hashAlg != SEC_OID_UNKNOWN && 714 hashAlg != SEC_OID_UNKNOWN &&
712 » hashCmp != hashAlg) { 715 hashCmp != hashAlg) {
713 » PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 716 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
714 » return SECFailure; 717 return SECFailure;
715 } 718 }
716 return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx); 719 return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
717 } 720 }
718 721
719 static SECStatus 722 static SECStatus
720 vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key, 723 vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
721 » const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg, 724 const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
722 » SECOidTag *hash, void *wincx) 725 SECOidTag *hash, void *wincx)
723 { 726 {
724 SECStatus rv; 727 SECStatus rv;
725 VFYContext *cx; 728 VFYContext *cx;
726 729
727 cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx); 730 cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
728 if (cx == NULL) 731 if (cx == NULL)
729 » return SECFailure; 732 return SECFailure;
730 733
731 rv = VFY_Begin(cx); 734 rv = VFY_Begin(cx);
732 if (rv == SECSuccess) { 735 if (rv == SECSuccess) {
733 » rv = VFY_Update(cx, (unsigned char *)buf, len); 736 rv = VFY_Update(cx, (unsigned char *)buf, len);
734 » if (rv == SECSuccess) 737 if (rv == SECSuccess)
735 » rv = VFY_End(cx); 738 rv = VFY_End(cx);
736 } 739 }
737 740
738 VFY_DestroyContext(cx, PR_TRUE); 741 VFY_DestroyContext(cx, PR_TRUE);
739 return rv; 742 return rv;
740 } 743 }
741 744
742 SECStatus 745 SECStatus
743 VFY_VerifyDataDirect(const unsigned char *buf, int len, 746 VFY_VerifyDataDirect(const unsigned char *buf, int len,
744 » » const SECKEYPublicKey *key, const SECItem *sig, 747 const SECKEYPublicKey *key, const SECItem *sig,
745 » » SECOidTag encAlg, SECOidTag hashAlg, 748 SECOidTag encAlg, SECOidTag hashAlg,
746 » » SECOidTag *hash, void *wincx) 749 SECOidTag *hash, void *wincx)
747 { 750 {
748 return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx); 751 return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
749 } 752 }
750 753
751 SECStatus 754 SECStatus
752 VFY_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key, 755 VFY_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
753 » const SECItem *sig, SECOidTag algid, void *wincx) 756 const SECItem *sig, SECOidTag algid, void *wincx)
754 { 757 {
755 SECOidTag encAlg, hashAlg; 758 SECOidTag encAlg, hashAlg;
756 SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg); 759 SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
757 if (rv != SECSuccess) { 760 if (rv != SECSuccess) {
758 » return rv; 761 return rv;
759 } 762 }
760 return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, wincx); 763 return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, wincx);
761 } 764 }
762 765
763 SECStatus 766 SECStatus
764 VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len, 767 VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len,
765 » » » const SECKEYPublicKey *key, 768 const SECKEYPublicKey *key,
766 » » » const SECItem *sig, 769 const SECItem *sig,
767 » » » const SECAlgorithmID *sigAlgorithm, 770 const SECAlgorithmID *sigAlgorithm,
768 » » » SECOidTag *hash, void *wincx) 771 SECOidTag *hash, void *wincx)
769 { 772 {
770 SECOidTag encAlg, hashAlg; 773 SECOidTag encAlg, hashAlg;
771 SECOidTag sigAlg = SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm); 774 SECOidTag sigAlg = SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm);
772 SECStatus rv = sec_DecodeSigAlg(key, sigAlg, 775 SECStatus rv = sec_DecodeSigAlg(key, sigAlg,
773 » » &sigAlgorithm->parameters, &encAlg, &hashAlg); 776 &sigAlgorithm->parameters, &encAlg, &hashAlg );
774 if (rv != SECSuccess) { 777 if (rv != SECSuccess) {
775 » return rv; 778 return rv;
776 } 779 }
777 return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx); 780 return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
778 } 781 }
OLDNEW
« no previous file with comments | « nss/lib/cryptohi/secsign.c ('k') | nss/lib/dev/ckhelper.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine