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

Side by Side Diff: nss/lib/cryptohi/dsautil.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. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 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 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/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #include "cryptohi.h" 4 #include "cryptohi.h"
5 #include "secasn1.h" 5 #include "secasn1.h"
6 #include "secitem.h" 6 #include "secitem.h"
7 #include "prerr.h" 7 #include "prerr.h"
8 8
9 #ifndef DSA1_SUBPRIME_LEN 9 #ifndef DSA1_SUBPRIME_LEN
10 #define DSA1_SUBPRIME_LEN 20» /* bytes */ 10 #define DSA1_SUBPRIME_LEN 20 /* bytes */
11 #endif 11 #endif
12 12
13 typedef struct { 13 typedef struct {
14 SECItem r; 14 SECItem r;
15 SECItem s; 15 SECItem s;
16 } DSA_ASN1Signature; 16 } DSA_ASN1Signature;
17 17
18 const SEC_ASN1Template DSA_SignatureTemplate[] = 18 const SEC_ASN1Template DSA_SignatureTemplate[] =
19 { 19 {
20 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(DSA_ASN1Signature) }, 20 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(DSA_ASN1Signature) },
21 { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature,r) }, 21 { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature, r) },
22 { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature,s) }, 22 { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature, s) },
23 { 0, } 23 { 0 }
24 }; 24 };
25 25
26 /* Input is variable length multi-byte integer, MSB first (big endian). 26 /* Input is variable length multi-byte integer, MSB first (big endian).
27 ** Most signficant bit of first byte is NOT treated as a sign bit. 27 ** Most signficant bit of first byte is NOT treated as a sign bit.
28 ** May be one or more leading bytes of zeros. 28 ** May be one or more leading bytes of zeros.
29 ** Output is variable length multi-byte integer, MSB first (big endian). 29 ** Output is variable length multi-byte integer, MSB first (big endian).
30 ** Most significant bit of first byte will be zero (positive sign bit) 30 ** Most significant bit of first byte will be zero (positive sign bit)
31 ** No more than one leading zero byte. 31 ** No more than one leading zero byte.
32 ** Caller supplies dest buffer, and assures that it is long enough, 32 ** Caller supplies dest buffer, and assures that it is long enough,
33 ** e.g. at least one byte longer that src's buffer. 33 ** e.g. at least one byte longer that src's buffer.
34 */ 34 */
35 void 35 void
36 DSAU_ConvertUnsignedToSigned(SECItem *dest, SECItem *src) 36 DSAU_ConvertUnsignedToSigned(SECItem *dest, SECItem *src)
37 { 37 {
38 unsigned char *pSrc = src->data; 38 unsigned char *pSrc = src->data;
39 unsigned char *pDst = dest->data; 39 unsigned char *pDst = dest->data;
40 unsigned int cntSrc = src->len; 40 unsigned int cntSrc = src->len;
41 41
42 /* skip any leading zeros. */ 42 /* skip any leading zeros. */
43 while (cntSrc && !(*pSrc)) { 43 while (cntSrc && !(*pSrc)) {
44 » pSrc++; 44 pSrc++;
45 » cntSrc--; 45 cntSrc--;
46 } 46 }
47 if (!cntSrc) { 47 if (!cntSrc) {
48 » *pDst = 0; 48 *pDst = 0;
49 » dest->len = 1; 49 dest->len = 1;
50 » return; 50 return;
51 } 51 }
52 52
53 if (*pSrc & 0x80) 53 if (*pSrc & 0x80)
54 » *pDst++ = 0; 54 *pDst++ = 0;
55 55
56 PORT_Memcpy(pDst, pSrc, cntSrc); 56 PORT_Memcpy(pDst, pSrc, cntSrc);
57 dest->len = (pDst - dest->data) + cntSrc; 57 dest->len = (pDst - dest->data) + cntSrc;
58 } 58 }
59 59
60 /* 60 /*
61 ** src is a buffer holding a signed variable length integer. 61 ** src is a buffer holding a signed variable length integer.
62 ** dest is a buffer which will be filled with an unsigned integer, 62 ** dest is a buffer which will be filled with an unsigned integer,
63 ** MSB first (big endian) with leading zeros, so that the last byte 63 ** MSB first (big endian) with leading zeros, so that the last byte
64 ** of src will be the LSB of the integer. The result will be exactly 64 ** of src will be the LSB of the integer. The result will be exactly
65 ** the length specified by the caller in dest->len. 65 ** the length specified by the caller in dest->len.
66 ** src can be shorter than dest. src can be longer than dst, but only 66 ** src can be shorter than dest. src can be longer than dst, but only
67 ** if the extra leading bytes are zeros. 67 ** if the extra leading bytes are zeros.
68 */ 68 */
69 SECStatus 69 SECStatus
70 DSAU_ConvertSignedToFixedUnsigned(SECItem *dest, SECItem *src) 70 DSAU_ConvertSignedToFixedUnsigned(SECItem *dest, SECItem *src)
71 { 71 {
72 unsigned char *pSrc = src->data; 72 unsigned char *pSrc = src->data;
73 unsigned char *pDst = dest->data; 73 unsigned char *pDst = dest->data;
74 unsigned int cntSrc = src->len; 74 unsigned int cntSrc = src->len;
75 unsigned int cntDst = dest->len; 75 unsigned int cntDst = dest->len;
76 int zCount = cntDst - cntSrc; 76 int zCount = cntDst - cntSrc;
77 77
78 if (zCount > 0) { 78 if (zCount > 0) {
79 » PORT_Memset(pDst, 0, zCount); 79 PORT_Memset(pDst, 0, zCount);
80 » PORT_Memcpy(pDst + zCount, pSrc, cntSrc); 80 PORT_Memcpy(pDst + zCount, pSrc, cntSrc);
81 » return SECSuccess; 81 return SECSuccess;
82 } 82 }
83 if (zCount <= 0) { 83 if (zCount <= 0) {
84 » /* Source is longer than destination. Check for leading zeros. */ 84 /* Source is longer than destination. Check for leading zeros. */
85 » while (zCount++ < 0) { 85 while (zCount++ < 0) {
86 » if (*pSrc++ != 0) 86 if (*pSrc++ != 0)
87 » » goto loser; 87 goto loser;
88 » } 88 }
89 } 89 }
90 PORT_Memcpy(pDst, pSrc, cntDst); 90 PORT_Memcpy(pDst, pSrc, cntDst);
91 return SECSuccess; 91 return SECSuccess;
92 92
93 loser: 93 loser:
94 PORT_SetError( PR_INVALID_ARGUMENT_ERROR ); 94 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
95 return SECFailure; 95 return SECFailure;
96 } 96 }
97 97
98 /* src is a "raw" ECDSA or DSA signature, the first half contains r 98 /* src is a "raw" ECDSA or DSA signature, the first half contains r
99 * and the second half contains s. dest is the DER encoded signature. 99 * and the second half contains s. dest is the DER encoded signature.
100 */ 100 */
101 static SECStatus 101 static SECStatus
102 common_EncodeDerSig(SECItem *dest, SECItem *src) 102 common_EncodeDerSig(SECItem *dest, SECItem *src)
103 { 103 {
104 SECItem * item; 104 SECItem *item;
105 SECItem srcItem; 105 SECItem srcItem;
106 DSA_ASN1Signature sig; 106 DSA_ASN1Signature sig;
107 unsigned char *signedR; 107 unsigned char *signedR;
108 unsigned char *signedS; 108 unsigned char *signedS;
109 unsigned int len; 109 unsigned int len;
110 110
111 /* Allocate memory with room for an extra byte that 111 /* Allocate memory with room for an extra byte that
112 * may be required if the top bit in the first byte 112 * may be required if the top bit in the first byte
113 * is already set. 113 * is already set.
114 */ 114 */
115 len = src->len/2; 115 len = src->len / 2;
116 signedR = (unsigned char *) PORT_Alloc(len + 1); 116 signedR = (unsigned char *)PORT_Alloc(len + 1);
117 if (!signedR) return SECFailure; 117 if (!signedR)
118 signedS = (unsigned char *) PORT_ZAlloc(len + 1); 118 return SECFailure;
119 signedS = (unsigned char *)PORT_ZAlloc(len + 1);
119 if (!signedS) { 120 if (!signedS) {
120 if (signedR) PORT_Free(signedR); 121 if (signedR)
121 » return SECFailure; 122 PORT_Free(signedR);
123 return SECFailure;
122 } 124 }
123 125
124 PORT_Memset(&sig, 0, sizeof(sig)); 126 PORT_Memset(&sig, 0, sizeof(sig));
125 127
126 /* Must convert r and s from "unsigned" integers to "signed" integers. 128 /* Must convert r and s from "unsigned" integers to "signed" integers.
127 ** If the high order bit of the first byte (MSB) is 1, then must 129 ** If the high order bit of the first byte (MSB) is 1, then must
128 ** prepend with leading zero. 130 ** prepend with leading zero.
129 ** Must remove all but one leading zero byte from numbers. 131 ** Must remove all but one leading zero byte from numbers.
130 */ 132 */
131 sig.r.type = siUnsignedInteger; 133 sig.r.type = siUnsignedInteger;
132 sig.r.data = signedR; 134 sig.r.data = signedR;
133 sig.r.len = sizeof signedR; 135 sig.r.len = sizeof signedR;
134 sig.s.type = siUnsignedInteger; 136 sig.s.type = siUnsignedInteger;
135 sig.s.data = signedS; 137 sig.s.data = signedS;
136 sig.s.len = sizeof signedR; 138 sig.s.len = sizeof signedR;
137 139
138 srcItem.data = src->data; 140 srcItem.data = src->data;
139 srcItem.len = len; 141 srcItem.len = len;
140 142
141 DSAU_ConvertUnsignedToSigned(&sig.r, &srcItem); 143 DSAU_ConvertUnsignedToSigned(&sig.r, &srcItem);
142 srcItem.data += len; 144 srcItem.data += len;
143 DSAU_ConvertUnsignedToSigned(&sig.s, &srcItem); 145 DSAU_ConvertUnsignedToSigned(&sig.s, &srcItem);
144 146
145 item = SEC_ASN1EncodeItem(NULL, dest, &sig, DSA_SignatureTemplate); 147 item = SEC_ASN1EncodeItem(NULL, dest, &sig, DSA_SignatureTemplate);
146 if (signedR) PORT_Free(signedR); 148 if (signedR)
147 if (signedS) PORT_Free(signedS); 149 PORT_Free(signedR);
150 if (signedS)
151 PORT_Free(signedS);
148 if (item == NULL) 152 if (item == NULL)
149 » return SECFailure; 153 return SECFailure;
150 154
151 /* XXX leak item? */ 155 /* XXX leak item? */
152 return SECSuccess; 156 return SECSuccess;
153 } 157 }
154 158
155 /* src is a DER-encoded ECDSA or DSA signature. 159 /* src is a DER-encoded ECDSA or DSA signature.
156 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated 160 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated
157 ** buffer containing the "raw" signature, which is len bytes of r, 161 ** buffer containing the "raw" signature, which is len bytes of r,
158 ** followed by len bytes of s. For DSA, len is the length of q. 162 ** followed by len bytes of s. For DSA, len is the length of q.
159 ** For ECDSA, len depends on the key size used to create the signature. 163 ** For ECDSA, len depends on the key size used to create the signature.
160 */ 164 */
161 static SECItem * 165 static SECItem *
162 common_DecodeDerSig(const SECItem *item, unsigned int len) 166 common_DecodeDerSig(const SECItem *item, unsigned int len)
163 { 167 {
164 SECItem * result = NULL; 168 SECItem *result = NULL;
165 SECStatus status; 169 SECStatus status;
166 DSA_ASN1Signature sig; 170 DSA_ASN1Signature sig;
167 SECItem dst; 171 SECItem dst;
168 172
169 PORT_Memset(&sig, 0, sizeof(sig)); 173 PORT_Memset(&sig, 0, sizeof(sig));
170 174
171 result = PORT_ZNew(SECItem); 175 result = PORT_ZNew(SECItem);
172 if (result == NULL) 176 if (result == NULL)
173 » goto loser; 177 goto loser;
174 178
175 result->len = 2 * len; 179 result->len = 2 * len;
176 result->data = (unsigned char*)PORT_Alloc(2 * len); 180 result->data = (unsigned char *)PORT_Alloc(2 * len);
177 if (result->data == NULL) 181 if (result->data == NULL)
178 » goto loser; 182 goto loser;
179 183
180 sig.r.type = siUnsignedInteger; 184 sig.r.type = siUnsignedInteger;
181 sig.s.type = siUnsignedInteger; 185 sig.s.type = siUnsignedInteger;
182 status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item); 186 status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item);
183 if (status != SECSuccess) 187 if (status != SECSuccess)
184 » goto loser; 188 goto loser;
185 189
186 /* Convert sig.r and sig.s from variable length signed integers to 190 /* Convert sig.r and sig.s from variable length signed integers to
187 ** fixed length unsigned integers. 191 ** fixed length unsigned integers.
188 */ 192 */
189 dst.data = result->data; 193 dst.data = result->data;
190 dst.len = len; 194 dst.len = len;
191 status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.r); 195 status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.r);
192 if (status != SECSuccess) 196 if (status != SECSuccess)
193 » goto loser; 197 goto loser;
194 198
195 dst.data += len; 199 dst.data += len;
196 status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.s); 200 status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.s);
197 if (status != SECSuccess) 201 if (status != SECSuccess)
198 » goto loser; 202 goto loser;
199 203
200 done: 204 done:
201 if (sig.r.data != NULL) 205 if (sig.r.data != NULL)
202 » PORT_Free(sig.r.data); 206 PORT_Free(sig.r.data);
203 if (sig.s.data != NULL) 207 if (sig.s.data != NULL)
204 » PORT_Free(sig.s.data); 208 PORT_Free(sig.s.data);
205 209
206 return result; 210 return result;
207 211
208 loser: 212 loser:
209 if (result != NULL) { 213 if (result != NULL) {
210 » SECITEM_FreeItem(result, PR_TRUE); 214 SECITEM_FreeItem(result, PR_TRUE);
211 » result = NULL; 215 result = NULL;
212 } 216 }
213 goto done; 217 goto done;
214 } 218 }
215 219
216 /* src is a "raw" DSA1 signature, 20 bytes of r followed by 20 bytes of s. 220 /* src is a "raw" DSA1 signature, 20 bytes of r followed by 20 bytes of s.
217 ** dest is the signature DER encoded. ? 221 ** dest is the signature DER encoded. ?
218 */ 222 */
219 SECStatus 223 SECStatus
220 DSAU_EncodeDerSig(SECItem *dest, SECItem *src) 224 DSAU_EncodeDerSig(SECItem *dest, SECItem *src)
221 { 225 {
222 PORT_Assert(src->len == 2 * DSA1_SUBPRIME_LEN); 226 PORT_Assert(src->len == 2 * DSA1_SUBPRIME_LEN);
223 if (src->len != 2 * DSA1_SUBPRIME_LEN) { 227 if (src->len != 2 * DSA1_SUBPRIME_LEN) {
224 » PORT_SetError( PR_INVALID_ARGUMENT_ERROR ); 228 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
225 » return SECFailure; 229 return SECFailure;
226 } 230 }
227 231
228 return common_EncodeDerSig(dest, src); 232 return common_EncodeDerSig(dest, src);
229 } 233 }
230 234
231 /* src is a "raw" DSA signature of length len (len/2 bytes of r followed 235 /* src is a "raw" DSA signature of length len (len/2 bytes of r followed
232 ** by len/2 bytes of s). dest is the signature DER encoded. 236 ** by len/2 bytes of s). dest is the signature DER encoded.
233 */ 237 */
234 SECStatus 238 SECStatus
235 DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, unsigned int len) 239 DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, unsigned int len)
236 { 240 {
237 241
238 PORT_Assert((src->len == len) && (len % 2 == 0)); 242 PORT_Assert((src->len == len) && (len % 2 == 0));
239 if ((src->len != len) || (src->len % 2 != 0)) { 243 if ((src->len != len) || (src->len % 2 != 0)) {
240 » PORT_SetError( PR_INVALID_ARGUMENT_ERROR ); 244 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
241 » return SECFailure; 245 return SECFailure;
242 } 246 }
243 247
244 return common_EncodeDerSig(dest, src); 248 return common_EncodeDerSig(dest, src);
245 } 249 }
246 250
247 /* src is a DER-encoded DSA signature. 251 /* src is a DER-encoded DSA signature.
248 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated 252 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated
249 ** buffer containing the "raw" DSA1 signature, which is 20 bytes of r, 253 ** buffer containing the "raw" DSA1 signature, which is 20 bytes of r,
250 ** followed by 20 bytes of s. 254 ** followed by 20 bytes of s.
251 */ 255 */
252 SECItem * 256 SECItem *
253 DSAU_DecodeDerSig(const SECItem *item) 257 DSAU_DecodeDerSig(const SECItem *item)
254 { 258 {
255 return common_DecodeDerSig(item, DSA1_SUBPRIME_LEN); 259 return common_DecodeDerSig(item, DSA1_SUBPRIME_LEN);
256 } 260 }
257 261
258 /* src is a DER-encoded ECDSA signature. 262 /* src is a DER-encoded ECDSA signature.
259 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated 263 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated
260 ** buffer containing the "raw" ECDSA signature of length len containing 264 ** buffer containing the "raw" ECDSA signature of length len containing
261 ** r followed by s (both padded to take up exactly len/2 bytes). 265 ** r followed by s (both padded to take up exactly len/2 bytes).
262 */ 266 */
263 SECItem * 267 SECItem *
264 DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len) 268 DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len)
265 { 269 {
266 return common_DecodeDerSig(item, len/2); 270 return common_DecodeDerSig(item, len / 2);
267 } 271 }
OLDNEW
« no previous file with comments | « nss/lib/cryptohi/cryptoht.h ('k') | nss/lib/cryptohi/keyhi.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698