OLD | NEW |
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 } |
OLD | NEW |