Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: nss/lib/util/pkcs1sig.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/util/pkcs1sig.h ('k') | nss/lib/util/portreg.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
6 #include "pkcs1sig.h"
7 #include "hasht.h"
8 #include "secerr.h"
9 #include "secasn1t.h"
10 #include "secoid.h"
11
12 typedef struct pkcs1PrefixStr pkcs1Prefix;
13 struct pkcs1PrefixStr {
14 unsigned int len;
15 PRUint8 *data;
16 };
17
18 typedef struct pkcs1PrefixesStr pkcs1Prefixes;
19 struct pkcs1PrefixesStr {
20 unsigned int digestLen;
21 pkcs1Prefix prefixWithParams;
22 pkcs1Prefix prefixWithoutParams;
23 };
24
25 /* The value for SGN_PKCS1_DIGESTINFO_MAX_PREFIX_LEN_EXCLUDING_OID is based on
26 * the possible prefix encodings as explained below.
27 */
28 #define MAX_PREFIX_LEN_EXCLUDING_OID 10
29
30 static SECStatus
31 encodePrefix(const SECOidData *hashOid, unsigned int digestLen,
32 pkcs1Prefix *prefix, PRBool withParams)
33 {
34 /* with params coding is:
35 * Sequence (2 bytes) {
36 * Sequence (2 bytes) {
37 * Oid (2 bytes) {
38 * Oid value (derOid->oid.len)
39 * }
40 * NULL (2 bytes)
41 * }
42 * OCTECT (2 bytes);
43 *
44 * without params coding is:
45 * Sequence (2 bytes) {
46 * Sequence (2 bytes) {
47 * Oid (2 bytes) {
48 * Oid value (derOid->oid.len)
49 * }
50 * }
51 * OCTECT (2 bytes);
52 */
53
54 unsigned int innerSeqLen = 2 + hashOid->oid.len;
55 unsigned int outerSeqLen = 2 + innerSeqLen + 2 + digestLen;
56 unsigned int extra = 0;
57
58 if (withParams) {
59 innerSeqLen += 2;
60 outerSeqLen += 2;
61 extra = 2;
62 }
63
64 if (innerSeqLen >= 128 ||
65 outerSeqLen >= 128 ||
66 (outerSeqLen + 2 - digestLen) >
67 (MAX_PREFIX_LEN_EXCLUDING_OID + hashOid->oid.len)) {
68 /* this is actually a library failure, It shouldn't happen */
69 PORT_SetError(SEC_ERROR_INVALID_ARGS);
70 return SECFailure;
71 }
72
73 prefix->len = 6 + hashOid->oid.len + extra + 2;
74 prefix->data = PORT_Alloc(prefix->len);
75 if (!prefix->data) {
76 PORT_SetError(SEC_ERROR_NO_MEMORY);
77 return SECFailure;
78 }
79
80 prefix->data[0] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED;
81 prefix->data[1] = outerSeqLen;
82 prefix->data[2] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED;
83 prefix->data[3] = innerSeqLen;
84 prefix->data[4] = SEC_ASN1_OBJECT_ID;
85 prefix->data[5] = hashOid->oid.len;
86 PORT_Memcpy(&prefix->data[6], hashOid->oid.data, hashOid->oid.len);
87 if (withParams) {
88 prefix->data[6 + hashOid->oid.len] = SEC_ASN1_NULL;
89 prefix->data[6 + hashOid->oid.len + 1] = 0;
90 }
91 prefix->data[6 + hashOid->oid.len + extra] = SEC_ASN1_OCTET_STRING;
92 prefix->data[6 + hashOid->oid.len + extra + 1] = digestLen;
93
94 return SECSuccess;
95 }
96
97 SECStatus
98 _SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg,
99 const SECItem* digest,
100 const SECItem* dataRecoveredFromSignature,
101 PRBool unsafeAllowMissingParameters)
102 {
103 SECOidData *hashOid;
104 pkcs1Prefixes pp;
105 const pkcs1Prefix* expectedPrefix;
106 SECStatus rv, rv2, rv3;
107
108 if (!digest || !digest->data ||
109 !dataRecoveredFromSignature || !dataRecoveredFromSignature->data) {
110 PORT_SetError(SEC_ERROR_INVALID_ARGS);
111 return SECFailure;
112 }
113
114 hashOid = SECOID_FindOIDByTag(digestAlg);
115 if (hashOid == NULL) {
116 PORT_SetError(SEC_ERROR_INVALID_ARGS);
117 return SECFailure;
118 }
119
120 pp.digestLen = digest->len;
121 pp.prefixWithParams.data = NULL;
122 pp.prefixWithoutParams.data = NULL;
123
124 rv2 = encodePrefix(hashOid, pp.digestLen, &pp.prefixWithParams, PR_TRUE);
125 rv3 = encodePrefix(hashOid, pp.digestLen, &pp.prefixWithoutParams, PR_FALSE) ;
126
127 rv = SECSuccess;
128 if (rv2 != SECSuccess || rv3 != SECSuccess) {
129 rv = SECFailure;
130 }
131
132 if (rv == SECSuccess) {
133 /* We don't attempt to avoid timing attacks on these comparisons because
134 * signature verification is a public key operation, not a private key
135 * operation.
136 */
137
138 if (dataRecoveredFromSignature->len ==
139 pp.prefixWithParams.len + pp.digestLen) {
140 expectedPrefix = &pp.prefixWithParams;
141 } else if (unsafeAllowMissingParameters &&
142 dataRecoveredFromSignature->len ==
143 pp.prefixWithoutParams.len + pp.digestLen) {
144 expectedPrefix = &pp.prefixWithoutParams;
145 } else {
146 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
147 rv = SECFailure;
148 }
149 }
150
151 if (rv == SECSuccess) {
152 if (memcmp(dataRecoveredFromSignature->data, expectedPrefix->data,
153 expectedPrefix->len) ||
154 memcmp(dataRecoveredFromSignature->data + expectedPrefix->len,
155 digest->data, digest->len)) {
156 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
157 rv = SECFailure;
158 }
159 }
160
161 if (pp.prefixWithParams.data) {
162 PORT_Free(pp.prefixWithParams.data);
163 }
164 if (pp.prefixWithoutParams.data) {
165 PORT_Free(pp.prefixWithoutParams.data);
166 }
167
168 return rv;
169 }
OLDNEW
« no previous file with comments | « nss/lib/util/pkcs1sig.h ('k') | nss/lib/util/portreg.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698