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

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

Powered by Google App Engine
This is Rietveld 408576698