| 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 | 
|---|