2 * Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 * opensslAsn1.h - ANS1 encode/decode of openssl object, libssnasn1 version
22 #include "opensslAsn1.h"
23 #include "BinaryKey.h"
24 #include "AppleCSPUtils.h"
25 #include "osKeyTemplates.h"
26 #include <openssl/err.h>
27 #include <openssl/bn.h>
28 #include <openssl/crypto.h>
30 #include <SecurityNssAsn1/SecNssCoder.h>
31 #include <SecurityNssAsn1/secerr.h>
32 #include <SecurityNssAsn1/keyTemplates.h>
33 #include <Security/debugging.h>
34 #include <Security/oidsalg.h>
38 #define sslAsn1Debug(args...) secdebug("sslAsn1", ##args)
42 #include <SecurityNssAsn1/secerr.h>
44 static void logAsnErr(
48 printf("Error on %s: %s\n", op
, SECErrorString(perr
));
51 #define logAsnErr(op, perr)
54 /* CSSM_DATA --> BIGNUM */
56 const CSSM_DATA
&cdata
)
58 BIGNUM
*bn
= BN_new();
61 rtn
= BN_bin2bn(cdata
.Data
, cdata
.Length
, bn
);
64 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
69 /* BIGNUM --> CSSM_DATA, mallocing from a SecNssCoder's PL_ArenaPool */
76 unsigned numBytes
= BN_num_bytes(bn
);
77 cdata
.Data
= (uint8
*)coder
.malloc(numBytes
);
78 if(cdata
.Data
== NULL
) {
79 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
81 cdata
.Length
= numBytes
;
82 BN_bn2bin(bn
, cdata
.Data
);
86 * CSSM_DATA --> unsigned int
88 unsigned cssmDataToInt(
89 const CSSM_DATA
&cdata
)
91 if((cdata
.Length
== 0) || (cdata
.Data
== NULL
)) {
94 unsigned len
= (unsigned)cdata
.Length
;
95 if(len
> sizeof(int)) {
96 logAsnErr("cssmDataToInt: Length error (%u)", len
);
97 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS
);
101 uint8
*cp
= cdata
.Data
;
102 for(unsigned i
=0; i
<len
; i
++) {
103 rtn
= (rtn
<< 8) | *cp
++;
109 * unsigned int --> CSSM_DATA, mallocing from an SecNssCoder
121 else if(num
< 0x10000) {
124 else if(num
< 0x1000000) {
130 cdata
.Data
= (uint8
*)coder
.malloc(len
);
132 uint8
*cp
= &cdata
.Data
[len
- 1];
133 for(unsigned i
=0; i
<len
; i
++) {
140 * Set up a encoded NULL for AlgorithmIdentifier.parameters,
143 static void nullAlgParams(
144 CSSM_X509_ALGORITHM_IDENTIFIER
&algId
)
146 static const uint8 encNull
[2] = { SEC_ASN1_NULL
, 0 };
147 CSSM_DATA encNullData
;
148 encNullData
.Data
= (uint8
*)encNull
;
149 encNullData
.Length
= 2;
151 algId
.parameters
= encNullData
;
155 #pragma mark *** RSA key encode/decode ***
158 * DER encode/decode RSA keys in various formats.
160 * Public key, CSSM_KEYBLOB_RAW_FORMAT_PKCS1
161 * -- compatible with BSAFE
162 * -- used for CSSM_KEYBLOB_RAW_FORMAT_DIGEST on both keys
164 static CSSM_RETURN
RSAPublicKeyDecodePKCS1(
170 NSS_RSAPublicKeyPKCS1 nssPubKey
;
172 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
173 PRErrorCode perr
= coder
.decode(p
, length
,
174 NSS_RSAPublicKeyPKCS1Template
, &nssPubKey
);
176 logAsnErr("decode(RSAPublicKeyPKCS1)", perr
);
177 return CSSMERR_CSP_INVALID_KEY
;
181 openKey
->n
= cssmDataToBn(nssPubKey
.modulus
);
182 openKey
->e
= cssmDataToBn(nssPubKey
.publicExponent
);
185 return CSSMERR_CSP_MEMORY_ERROR
;
190 static CSSM_RETURN
RSAPublicKeyEncodePKCS1(
193 CssmOwnedData
&encodedKey
)
195 /* convert to NSS_RSAPublicKeyPKCS1 */
196 NSS_RSAPublicKeyPKCS1 nssPubKey
;
199 bnToCssmData(openKey
->n
, nssPubKey
.modulus
, coder
);
200 bnToCssmData(openKey
->e
, nssPubKey
.publicExponent
, coder
);
203 return CSSMERR_CSP_MEMORY_ERROR
;
207 prtn
= SecNssEncodeItemOdata(&nssPubKey
,
208 NSS_RSAPublicKeyPKCS1Template
, encodedKey
);
210 return CSSMERR_CSP_MEMORY_ERROR
;
216 * SubjectPublicKeyInfo, as used by openssl.
217 * The subjectPublicKey component is a PKCS1-style RSAPublicKey.
219 static CSSM_RETURN
RSAPublicKeyDecodeX509(
225 CSSM_X509_SUBJECT_PUBLIC_KEY_INFO nssPubKeyInfo
;
228 memset(&nssPubKeyInfo
, 0, sizeof(nssPubKeyInfo
));
229 perr
= coder
.decode(p
, length
, NSS_SubjectPublicKeyInfoTemplate
,
232 logAsnErr("decode(RSA SubjectPublicKeyInfo)", perr
);
233 return CSSMERR_CSP_INVALID_KEY
;
236 /* verify alg identifier */
237 const CSSM_OID
*oid
= &nssPubKeyInfo
.algorithm
.algorithm
;
238 if(!cspCompareCssmData(oid
, &CSSMOID_RSA
)) {
239 sslAsn1Debug("RSAPublicKeyDecodeX509: bad OID");
240 return CSSMERR_CSP_INVALID_KEY
;
243 /* decode the raw bits */
244 CSSM_DATA
*pubKey
= &nssPubKeyInfo
.subjectPublicKey
;
245 /* decoded length was in bits */
246 pubKey
->Length
= (pubKey
->Length
+ 7) / 8;
247 return RSAPublicKeyDecodePKCS1(coder
, openKey
, pubKey
->Data
,
251 static CSSM_RETURN
RSAPublicKeyEncodeX509(
254 CssmOwnedData
&encodedKey
)
256 CssmAutoData
aData(CssmAllocator::standard());
259 /* First get an encoded PKCS1-style RSAPublicKey */
260 crtn
= RSAPublicKeyEncodePKCS1(coder
, openKey
, aData
);
266 * That's the AsnBits subjectPublicKey component of a
267 * SubjectPublicKeyInfo
269 CSSM_X509_SUBJECT_PUBLIC_KEY_INFO nssPubKeyInfo
;
270 memset(&nssPubKeyInfo
, 0, sizeof(nssPubKeyInfo
));
271 nssPubKeyInfo
.subjectPublicKey
.Data
= (uint8
*)aData
.data();
272 nssPubKeyInfo
.subjectPublicKey
.Length
= aData
.length() * 8;
274 CSSM_X509_ALGORITHM_IDENTIFIER
&algId
= nssPubKeyInfo
.algorithm
;
275 algId
.algorithm
= CSSMOID_RSA
;
277 /* NULL algorithm paramneters, always in this case */
278 nullAlgParams(algId
);
282 perr
= SecNssEncodeItemOdata(&nssPubKeyInfo
,
283 NSS_SubjectPublicKeyInfoTemplate
, encodedKey
);
286 logAsnErr("encode(RSA SubjectPublicKeyInfo)", perr
);
287 return CSSMERR_CSP_MEMORY_ERROR
;
293 * RSA private key, PKCS1 format, used by openssl.
295 static CSSM_RETURN
RSAPrivateKeyDecodePKCS1(
301 NSS_RSAPrivateKeyPKCS1 nssPrivKey
;
304 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
305 perr
= coder
.decode(p
, length
, NSS_RSAPrivateKeyPKCS1Template
, &nssPrivKey
);
307 logAsnErr("decode(RSAPrivateKeyPKCS)", perr
);
308 return CSSMERR_CSP_INVALID_KEY
;
311 /* convert nssPrivKey fields to RSA key fields */
313 openKey
->version
= cssmDataToInt(nssPrivKey
.version
);
314 openKey
->n
= cssmDataToBn(nssPrivKey
.modulus
);
315 openKey
->e
= cssmDataToBn(nssPrivKey
.publicExponent
);
316 openKey
->d
= cssmDataToBn(nssPrivKey
.privateExponent
);
317 openKey
->p
= cssmDataToBn(nssPrivKey
.prime1
);
318 openKey
->q
= cssmDataToBn(nssPrivKey
.prime2
);
319 openKey
->dmp1
= cssmDataToBn(nssPrivKey
.exponent1
);
320 openKey
->dmq1
= cssmDataToBn(nssPrivKey
.exponent2
);
321 openKey
->iqmp
= cssmDataToBn(nssPrivKey
.coefficient
);
324 return CSSMERR_CSP_MEMORY_ERROR
;
329 static CSSM_RETURN
RSAPrivateKeyEncodePKCS1(
332 CssmOwnedData
&encodedKey
)
334 NSS_RSAPrivateKeyPKCS1 nssPrivKey
;
337 /* convert to NSS_RSAPrivateKeyPKCS1 */
339 intToCssmData(openKey
->version
, nssPrivKey
.version
, coder
);
340 bnToCssmData(openKey
->n
, nssPrivKey
.modulus
, coder
);
341 bnToCssmData(openKey
->e
, nssPrivKey
.publicExponent
, coder
);
342 bnToCssmData(openKey
->d
, nssPrivKey
.privateExponent
, coder
);
343 bnToCssmData(openKey
->p
, nssPrivKey
.prime1
, coder
);
344 bnToCssmData(openKey
->q
, nssPrivKey
.prime2
, coder
);
345 bnToCssmData(openKey
->dmp1
, nssPrivKey
.exponent1
, coder
);
346 bnToCssmData(openKey
->dmq1
, nssPrivKey
.exponent2
, coder
);
347 bnToCssmData(openKey
->iqmp
, nssPrivKey
.coefficient
, coder
);
351 return CSSMERR_CSP_MEMORY_ERROR
;
355 perr
= SecNssEncodeItemOdata(&nssPrivKey
, NSS_RSAPrivateKeyPKCS1Template
,
358 logAsnErr("encode(RSAPrivateKeyPKCS1)", perr
);
359 return CSSMERR_CSP_MEMORY_ERROR
;
365 * RSA private key, PKCS8, compatible with BSAFE.
367 static CSSM_RETURN
RSAPrivateKeyDecodePKCS8(
373 NSS_PrivateKeyInfo nssPrivKeyInfo
;
376 memset(&nssPrivKeyInfo
, 0, sizeof(nssPrivKeyInfo
));
377 perr
= coder
.decode(p
, length
, NSS_PrivateKeyInfoTemplate
, &nssPrivKeyInfo
);
379 logAsnErr("decode(PrivateKeyInfo)", perr
);
380 return CSSMERR_CSP_INVALID_KEY
;
383 /* verify alg identifier */
384 const CSSM_OID
*oid
= &nssPrivKeyInfo
.algorithm
.algorithm
;
385 if(!cspCompareCssmData(oid
, &CSSMOID_RSA
)) {
386 sslAsn1Debug("RSAPrivateKeyDecodePKCS8: bad OID");
387 return CSSMERR_CSP_INVALID_KEY
;
391 * nssPrivKeyInfo.privateKey is an octet string which needs
392 * subsequent decoding
394 CSSM_DATA
*privKey
= &nssPrivKeyInfo
.privateKey
;
395 return RSAPrivateKeyDecodePKCS1(coder
, openKey
,
396 privKey
->Data
, privKey
->Length
);
399 static CSSM_RETURN
RSAPrivateKeyEncodePKCS8(
402 CssmOwnedData
&encodedKey
)
405 /* First get PKCS1-style encoding */
406 CssmAutoData
aData(CssmAllocator::standard());
407 CSSM_RETURN crtn
= RSAPrivateKeyEncodePKCS1(coder
, openKey
, aData
);
412 /* that encoding is the privateKey field of a NSS_PrivateKeyInfo */
413 NSS_PrivateKeyInfo nssPrivKeyInfo
;
414 memset(&nssPrivKeyInfo
, 0, sizeof(nssPrivKeyInfo
));
415 nssPrivKeyInfo
.privateKey
.Data
= (uint8
*)aData
.data();
416 nssPrivKeyInfo
.privateKey
.Length
= aData
.length();
418 CSSM_X509_ALGORITHM_IDENTIFIER
&algId
= nssPrivKeyInfo
.algorithm
;
419 algId
.algorithm
= CSSMOID_RSA
;
421 /* NULL algorithm paramneters, always in this case */
422 nullAlgParams(algId
);
424 /* FIXME : attributes? */
427 nssPrivKeyInfo
.version
.Data
= &vers
;
428 nssPrivKeyInfo
.version
.Length
= 1;
432 perr
= SecNssEncodeItemOdata(&nssPrivKeyInfo
,
433 NSS_PrivateKeyInfoTemplate
, encodedKey
);
436 logAsnErr("encode(RSA PrivateKeyInfo)", perr
);
437 return CSSMERR_CSP_MEMORY_ERROR
;
442 CSSM_RETURN
RSAPublicKeyDecode(
444 CSSM_KEYBLOB_FORMAT format
,
451 case CSSM_KEYBLOB_RAW_FORMAT_PKCS1
:
452 return RSAPublicKeyDecodePKCS1(coder
, openKey
, p
, length
);
453 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
454 return RSAPublicKeyDecodeX509(coder
, openKey
, p
, length
);
457 return CSSMERR_CSP_INTERNAL_ERROR
;
461 CSSM_RETURN
RSAPublicKeyEncode(
463 CSSM_KEYBLOB_FORMAT format
,
464 CssmOwnedData
&encodedKey
)
469 case CSSM_KEYBLOB_RAW_FORMAT_PKCS1
:
470 return RSAPublicKeyEncodePKCS1(coder
, openKey
, encodedKey
);
471 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
472 return RSAPublicKeyEncodeX509(coder
, openKey
, encodedKey
);
475 return CSSMERR_CSP_INTERNAL_ERROR
;
479 CSSM_RETURN
RSAPrivateKeyDecode(
481 CSSM_KEYBLOB_FORMAT format
,
488 case CSSM_KEYBLOB_RAW_FORMAT_PKCS1
:
489 return RSAPrivateKeyDecodePKCS1(coder
, openKey
, p
, length
);
490 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
:
491 return RSAPrivateKeyDecodePKCS8(coder
, openKey
, p
, length
);
494 return CSSMERR_CSP_INTERNAL_ERROR
;
498 CSSM_RETURN
RSAPrivateKeyEncode(
500 CSSM_KEYBLOB_FORMAT format
,
501 CssmOwnedData
&encodedKey
)
506 case CSSM_KEYBLOB_RAW_FORMAT_PKCS1
:
507 return RSAPrivateKeyEncodePKCS1(coder
, openKey
, encodedKey
);
508 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
:
509 return RSAPrivateKeyEncodePKCS8(coder
, openKey
, encodedKey
);
512 return CSSMERR_CSP_INTERNAL_ERROR
;
517 #pragma mark *** DSA key encode/decode ***
523 /* NSS_DSAAlgorithmIdBSAFE <--> DSA->{p,g,q} */
524 static void dsaToNssAlgIdBSAFE(
526 NSS_DSAAlgorithmIdBSAFE
&algId
,
529 /* non-standard, BSAFE-specific OID */
530 algId
.algorithm
= CSSMOID_DSA
; // not mallocd
531 unsigned numBits
= BN_num_bits(openKey
->p
);
532 intToCssmData(numBits
, algId
.params
.keySizeInBits
, coder
);
533 bnToCssmData(openKey
->p
, algId
.params
.p
, coder
);
534 bnToCssmData(openKey
->q
, algId
.params
.q
, coder
);
535 bnToCssmData(openKey
->g
, algId
.params
.g
, coder
);
538 static CSSM_RETURN
nssAlgIdToDsaBSAFE(
539 NSS_DSAAlgorithmIdBSAFE
&algId
,
542 /* non-standard, BSAFE-specific OID */
543 if(!cspCompareCssmData(&algId
.algorithm
, &CSSMOID_DSA
)) {
544 sslAsn1Debug("nssAlgIdToDsaBSAFE: bad OID");
545 return CSSMERR_CSP_INVALID_KEY
;
547 openKey
->p
= cssmDataToBn(algId
.params
.p
);
548 openKey
->q
= cssmDataToBn(algId
.params
.q
);
549 openKey
->g
= cssmDataToBn(algId
.params
.g
);
553 /* NSS_DSAAlgorithmIdX509 <--> DSA->{p,g,q} */
554 static void dsaToNssAlgIdX509(
556 NSS_DSAAlgorithmIdX509
&algId
,
559 algId
.algorithm
= CSSMOID_DSA_CMS
; // not mallocd
560 bnToCssmData(openKey
->p
, algId
.params
->p
, coder
);
561 bnToCssmData(openKey
->q
, algId
.params
->q
, coder
);
562 bnToCssmData(openKey
->g
, algId
.params
->g
, coder
);
565 static CSSM_RETURN
nssAlgIdToDsaX509(
566 NSS_DSAAlgorithmIdX509
&algId
,
569 if(!cspCompareCssmData(&algId
.algorithm
, &CSSMOID_DSA_CMS
) &&
570 !cspCompareCssmData(&algId
.algorithm
, &CSSMOID_DSA_JDK
)) {
571 sslAsn1Debug("nssAlgIdToDsaX509: bad OID");
572 return CSSMERR_CSP_INVALID_KEY
;
574 /* these might be absent per CMS */
575 if(algId
.params
== NULL
) {
578 openKey
->p
= cssmDataToBn(algId
.params
->p
);
579 openKey
->q
= cssmDataToBn(algId
.params
->q
);
580 openKey
->g
= cssmDataToBn(algId
.params
->g
);
585 * DSA public keys, FIPS186 format.
586 * Compatible with BSAFE.
588 CSSM_RETURN
DSAPublicKeyDecodeFIPS186(
594 NSS_DSAPublicKeyBSAFE nssPubKey
;
598 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
599 perr
= coder
.decode(p
, length
, NSS_DSAPublicKeyBSAFETemplate
,
602 logAsnErr("decode(DSAPublicKeyBSAFE)", perr
);
603 return CSSMERR_CSP_INVALID_KEY
;
606 /* BSAFE style DSA-specific alg params */
607 NSS_DSAAlgorithmIdBSAFE
&algId
= nssPubKey
.dsaAlg
;
608 crtn
= nssAlgIdToDsaBSAFE(algId
, openKey
);
613 /* inside of nssPubKey.publicKey is the DER-encoding of a
614 * ASN Integer; decoded length was in bits */
615 nssPubKey
.publicKey
.Length
= (nssPubKey
.publicKey
.Length
+ 7) / 8;
616 CSSM_DATA pubKeyBytes
;
617 perr
= coder
.decodeItem(nssPubKey
.publicKey
,
618 SEC_UnsignedIntegerTemplate
,
621 logAsnErr("decode(NSS_DSAPublicKeyBSAFE.publicKey)", perr
);
622 return CSSMERR_CSP_INVALID_KEY
;
624 openKey
->pub_key
= cssmDataToBn(pubKeyBytes
);
626 if(openKey
->pub_key
== NULL
) {
627 return CSSMERR_CSP_INVALID_KEY
;
632 CSSM_RETURN
DSAPublicKeyEncodeFIPS186(
635 CssmOwnedData
&encodedKey
)
638 /* convert to NSS_DSAPublicKeyBSAFE */
639 NSS_DSAPublicKeyBSAFE nssPubKey
;
640 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
641 dsaToNssAlgIdBSAFE(openKey
, nssPubKey
.dsaAlg
, coder
);
644 * publicKey is the DER-encoding of a ASN INTEGER wrapped in
649 bnToCssmData(openKey
->pub_key
, pubKeyRaw
, coder
);
650 perr
= coder
.encodeItem(&pubKeyRaw
, SEC_UnsignedIntegerTemplate
,
651 nssPubKey
.publicKey
);
653 logAsnErr("encodeItem(DSAPublicKeyBSAFE.publicKey)", perr
);
654 return CSSMERR_CSP_MEMORY_ERROR
;
656 nssPubKey
.publicKey
.Length
*= 8;
659 SecNssEncodeItemOdata(&nssPubKey
, NSS_DSAPublicKeyBSAFETemplate
,
665 return CSSMERR_CSP_MEMORY_ERROR
;
670 * DSA private keys, FIPS186 format.
671 * Compatible with BSAFE.
673 CSSM_RETURN
DSAPrivateKeyDecodeFIPS186(
679 NSS_DSAPrivateKeyBSAFE nssPrivKeyInfo
;
682 memset(&nssPrivKeyInfo
, 0, sizeof(nssPrivKeyInfo
));
683 perr
= coder
.decode(p
, length
, NSS_DSAPrivateKeyBSAFETemplate
,
686 logAsnErr("decode(DSA PrivateKeyInfo)", perr
);
687 return CSSMERR_CSP_INVALID_KEY
;
690 CSSM_RETURN crtn
= nssAlgIdToDsaBSAFE(nssPrivKeyInfo
.dsaAlg
, openKey
);
695 /* nssPrivKeyInfo.privateKey is the DER-encoding of a
696 * DSAPrivateKeyOcts... */
699 NSS_DSAPrivateKeyOcts keyOcts
;
701 perr
= coder
.decodeItem(nssPrivKeyInfo
.privateKey
,
702 NSS_DSAPrivateKeyOctsTemplate
, &keyOcts
);
704 logAsnErr("decode(DSA PrivateKeyInfoOcts)", perr
);
705 return CSSMERR_CSP_INVALID_KEY
;
708 openKey
->priv_key
= cssmDataToBn(keyOcts
.privateKey
);
709 if(openKey
->priv_key
== NULL
) {
710 return CSSMERR_CSP_INVALID_KEY
;
715 return CSSMERR_CSP_INVALID_KEY
;
719 CSSM_RETURN
DSAPrivateKeyEncodeFIPS186(
722 CssmOwnedData
&encodedKey
)
725 /* First convert into a NSS_DSAPrivateKeyBSAFE */
726 NSS_DSAPrivateKeyBSAFE nssPrivKey
;
727 intToCssmData(openKey
->version
, nssPrivKey
.version
, coder
);
728 dsaToNssAlgIdBSAFE(openKey
, nssPrivKey
.dsaAlg
, coder
);
730 /* nssPrivKey.privateKey is the DER-encoding of one of these... */
731 NSS_DSAPrivateKeyOcts privKeyOcts
;
732 bnToCssmData(openKey
->priv_key
, privKeyOcts
.privateKey
, coder
);
734 /* DER encode the privateKey portion into arena pool memory
735 * into NSS_DSAPrivateKeyPKCS8.privateKey */
736 coder
.encodeItem(&privKeyOcts
, NSS_DSAPrivateKeyOctsTemplate
,
737 nssPrivKey
.privateKey
);
739 /* DER encode the whole thing */
741 perr
= SecNssEncodeItemOdata(&nssPrivKey
,
742 NSS_DSAPrivateKeyBSAFETemplate
, encodedKey
);
747 return CSSMERR_CSP_MEMORY_ERROR
;
752 * DSA private keys, PKCS8/SMIME format.
754 CSSM_RETURN
DSAPrivateKeyDecodePKCS8(
760 NSS_DSAPrivateKeyPKCS8 nssPrivKeyInfo
;
763 memset(&nssPrivKeyInfo
, 0, sizeof(nssPrivKeyInfo
));
764 perr
= coder
.decode(p
, length
, NSS_DSAPrivateKeyPKCS8Template
,
767 logAsnErr("decode(DSA NSS_DSAPrivateKeyPKCS8)", perr
);
768 return CSSMERR_CSP_INVALID_KEY
;
771 CSSM_RETURN crtn
= nssAlgIdToDsaX509(nssPrivKeyInfo
.dsaAlg
, openKey
);
777 * Post-decode, nssPrivKeyInfo.privateKey is the DER-encoding of a
782 CSSM_DATA privKeyInt
= {0, NULL
};
784 perr
= coder
.decodeItem(nssPrivKeyInfo
.privateKey
,
785 SEC_UnsignedIntegerTemplate
, &privKeyInt
);
787 logAsnErr("decode(DSA nssPrivKeyInfo.privateKey)", perr
);
788 return CSSMERR_CSP_INVALID_KEY
;
791 openKey
->priv_key
= cssmDataToBn(privKeyInt
);
792 if(openKey
->priv_key
== NULL
) {
793 return CSSMERR_CSP_INVALID_KEY
;
798 return CSSMERR_CSP_INVALID_KEY
;
802 CSSM_RETURN
DSAPrivateKeyEncodePKCS8(
805 CssmOwnedData
&encodedKey
)
808 /* First convert into a NSS_DSAPrivateKeyPKCS8 */
809 NSS_DSAPrivateKeyPKCS8 nssPrivKey
;
810 NSS_DSAAlgParams algParams
;
811 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
812 memset(&algParams
, 0, sizeof(algParams
));
813 nssPrivKey
.dsaAlg
.params
= &algParams
;
814 intToCssmData(openKey
->version
, nssPrivKey
.version
, coder
);
815 dsaToNssAlgIdX509(openKey
, nssPrivKey
.dsaAlg
, coder
);
817 /* pre-encode, nssPrivKey.privateKey is the DER-encoding of
818 * an ASN integer... */
819 CSSM_DATA privKeyInt
;
820 bnToCssmData(openKey
->priv_key
, privKeyInt
, coder
);
822 /* DER encode the privateKey portion into arena pool memory
823 * into NSS_DSAPrivateKeyPKCS8.privateKey */
824 coder
.encodeItem(&privKeyInt
, SEC_UnsignedIntegerTemplate
,
825 nssPrivKey
.privateKey
);
827 /* DER encode the whole thing */
829 perr
= SecNssEncodeItemOdata(&nssPrivKey
,
830 NSS_DSAPrivateKeyPKCS8Template
, encodedKey
);
835 return CSSMERR_CSP_MEMORY_ERROR
;
840 * DSA public key, X509/openssl format.
842 static CSSM_RETURN
DSAPublicKeyDecodeX509(
848 NSS_DSAPublicKeyX509 nssPubKey
;
852 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
853 perr
= coder
.decode(p
, length
, NSS_DSAPublicKeyX509Template
,
856 logAsnErr("decode(DSAPublicKeyX509)", perr
);
857 return CSSMERR_CSP_INVALID_KEY
;
860 /* X509 style DSA-specific alg params */
861 NSS_DSAAlgorithmIdX509
&algId
= nssPubKey
.dsaAlg
;
862 crtn
= nssAlgIdToDsaX509(algId
, openKey
);
867 /* inside of nssPubKey.publicKey is the DER-encoding of a
868 * ASN Integer; decoded length was in bits */
869 nssPubKey
.publicKey
.Length
= (nssPubKey
.publicKey
.Length
+ 7) / 8;
870 CSSM_DATA pubKeyBytes
= {0, NULL
};
871 perr
= coder
.decodeItem(nssPubKey
.publicKey
,
872 SEC_UnsignedIntegerTemplate
,
875 logAsnErr("decode(NSS_DSAPublicKeyX509.publicKey)", perr
);
876 return CSSMERR_CSP_INVALID_KEY
;
878 openKey
->pub_key
= cssmDataToBn(pubKeyBytes
);
880 if(openKey
->pub_key
== NULL
) {
881 return CSSMERR_CSP_INVALID_KEY
;
886 static CSSM_RETURN
DSAPublicKeyEncodeX509(
889 CssmOwnedData
&encodedKey
)
892 /* convert to NSS_DSAPublicKeyX509 */
893 NSS_DSAPublicKeyX509 nssPubKey
;
894 NSS_DSAAlgParams algParams
;
895 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
896 memset(&algParams
, 0, sizeof(algParams
));
897 nssPubKey
.dsaAlg
.params
= &algParams
;
898 dsaToNssAlgIdX509(openKey
, nssPubKey
.dsaAlg
, coder
);
901 * publicKey is the DER-encoding of a ASN INTEGER wrapped in
906 bnToCssmData(openKey
->pub_key
, pubKeyRaw
, coder
);
907 perr
= coder
.encodeItem(&pubKeyRaw
, SEC_UnsignedIntegerTemplate
,
908 nssPubKey
.publicKey
);
910 logAsnErr("encodeItem(DSAPublicKeyX509.publicKey)", perr
);
911 return CSSMERR_CSP_MEMORY_ERROR
;
913 nssPubKey
.publicKey
.Length
*= 8;
916 SecNssEncodeItemOdata(&nssPubKey
, NSS_DSAPublicKeyX509Template
,
922 return CSSMERR_CSP_MEMORY_ERROR
;
927 * Encode public key portion only for calculating key digest.
928 * Note this works just fine on a partial DSA public key, i.e.,
929 * A DSA public key's digest-capable blob is the same whether or
930 * not the DSA key has its DSA parameters p, q, and g.
932 static CSSM_RETURN
DSAPublicKeyEncodeHashable(
935 CssmOwnedData
&encodedKey
)
939 * publicKey is the DER-encoding of an ASN integer
942 bnToCssmData(openKey
->pub_key
, pubKey
, coder
);
945 perr
= SecNssEncodeItemOdata(&pubKey
, SEC_UnsignedIntegerTemplate
,
948 logAsnErr("encode(DSAPubHashable)", perr
);
949 return CSSMERR_CSP_MEMORY_ERROR
;
955 return CSSMERR_CSP_MEMORY_ERROR
;
960 * DSA private key, custom openssl format.
962 static CSSM_RETURN
DSAPrivateKeyDecodeOpenssl(
968 NSS_DSAPrivateKeyOpenssl nssPrivKey
;
971 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
972 perr
= coder
.decode(p
, length
, NSS_DSAPrivateKeyOpensslTemplate
,
975 logAsnErr("decode(DSAPrivateKeyOpenssl)", perr
);
976 return CSSMERR_CSP_INVALID_KEY
;
979 /* convert nssPrivKey fields to RSA key fields */
981 openKey
->version
= cssmDataToInt(nssPrivKey
.version
);
982 openKey
->p
= cssmDataToBn(nssPrivKey
.p
);
983 openKey
->q
= cssmDataToBn(nssPrivKey
.q
);
984 openKey
->g
= cssmDataToBn(nssPrivKey
.g
);
985 openKey
->pub_key
= cssmDataToBn(nssPrivKey
.pub
);
986 openKey
->priv_key
= cssmDataToBn(nssPrivKey
.priv
);
989 return CSSMERR_CSP_MEMORY_ERROR
;
994 static CSSM_RETURN
DSAPrivateKeyEncodeOpenssl(
997 CssmOwnedData
&encodedKey
)
999 NSS_DSAPrivateKeyOpenssl nssPrivKey
;
1002 /* convert to NSS_DSAPrivateKeyOpenssl */
1004 intToCssmData(openKey
->version
, nssPrivKey
.version
, coder
);
1005 bnToCssmData(openKey
->p
, nssPrivKey
.p
, coder
);
1006 bnToCssmData(openKey
->q
, nssPrivKey
.q
, coder
);
1007 bnToCssmData(openKey
->g
, nssPrivKey
.g
, coder
);
1008 bnToCssmData(openKey
->pub_key
, nssPrivKey
.pub
, coder
);
1009 bnToCssmData(openKey
->priv_key
, nssPrivKey
.priv
, coder
);
1013 return CSSMERR_CSP_MEMORY_ERROR
;
1017 perr
= SecNssEncodeItemOdata(&nssPrivKey
, NSS_DSAPrivateKeyOpensslTemplate
,
1020 logAsnErr("encode(DSAPrivateKeyOpenssl)", perr
);
1021 return CSSMERR_CSP_MEMORY_ERROR
;
1026 CSSM_RETURN
DSAPublicKeyDecode(
1028 CSSM_KEYBLOB_FORMAT format
,
1035 case CSSM_KEYBLOB_RAW_FORMAT_FIPS186
:
1036 return DSAPublicKeyDecodeFIPS186(coder
, openKey
, p
, length
);
1037 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
1038 return DSAPublicKeyDecodeX509(coder
, openKey
, p
, length
);
1041 return CSSMERR_CSP_INTERNAL_ERROR
;
1045 CSSM_RETURN
DSAPublicKeyEncode(
1047 CSSM_KEYBLOB_FORMAT format
,
1048 CssmOwnedData
&encodedKey
)
1053 case CSSM_KEYBLOB_RAW_FORMAT_FIPS186
:
1054 return DSAPublicKeyEncodeFIPS186(coder
, openKey
, encodedKey
);
1055 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
1056 return DSAPublicKeyEncodeX509(coder
, openKey
, encodedKey
);
1057 case CSSM_KEYBLOB_RAW_FORMAT_DIGEST
:
1058 return DSAPublicKeyEncodeHashable(coder
, openKey
, encodedKey
);
1061 return CSSMERR_CSP_INTERNAL_ERROR
;
1065 CSSM_RETURN
DSAPrivateKeyDecode(
1067 CSSM_KEYBLOB_FORMAT format
,
1074 case CSSM_KEYBLOB_RAW_FORMAT_FIPS186
:
1075 return DSAPrivateKeyDecodeFIPS186(coder
, openKey
, p
, length
);
1076 case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL
:
1077 return DSAPrivateKeyDecodeOpenssl(coder
, openKey
, p
, length
);
1078 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
:
1079 return DSAPrivateKeyDecodePKCS8(coder
, openKey
, p
, length
);
1082 return CSSMERR_CSP_INTERNAL_ERROR
;
1086 CSSM_RETURN
DSAPrivateKeyEncode(
1088 CSSM_KEYBLOB_FORMAT format
,
1089 CssmOwnedData
&encodedKey
)
1094 case CSSM_KEYBLOB_RAW_FORMAT_FIPS186
:
1095 return DSAPrivateKeyEncodeFIPS186(coder
, openKey
, encodedKey
);
1096 case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL
:
1097 return DSAPrivateKeyEncodeOpenssl(coder
, openKey
, encodedKey
);
1098 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
:
1099 return DSAPrivateKeyEncodePKCS8(coder
, openKey
, encodedKey
);
1102 return CSSMERR_CSP_INTERNAL_ERROR
;
1107 #pragma mark *** DSA Signature encode/decode ***
1109 CSSM_RETURN
DSASigEncode(
1111 CssmOwnedData
&encodedSig
)
1113 /* temp allocs from this pool */
1115 /* convert to NSS_DSASignature */
1116 NSS_DSASignature nssSig
;
1119 bnToCssmData(openSig
->r
, nssSig
.r
, coder
);
1120 bnToCssmData(openSig
->s
, nssSig
.s
, coder
);
1124 return CSSMERR_CSP_MEMORY_ERROR
;
1127 PRErrorCode prtn
= SecNssEncodeItemOdata(&nssSig
,
1128 NSS_DSASignatureTemplate
, encodedSig
);
1130 return CSSMERR_CSP_MEMORY_ERROR
;
1135 CSSM_RETURN
DSASigDecode(
1140 NSS_DSASignature nssSig
;
1143 memset(&nssSig
, 0, sizeof(nssSig
));
1144 PRErrorCode perr
= coder
.decode(p
, length
,
1145 NSS_DSASignatureTemplate
, &nssSig
);
1147 logAsnErr("decode(DSASigDecode)", perr
);
1148 return CSSMERR_CSP_INVALID_SIGNATURE
;
1152 openSig
->r
= cssmDataToBn(nssSig
.r
);
1153 openSig
->s
= cssmDataToBn(nssSig
.s
);
1156 return CSSMERR_CSP_MEMORY_ERROR
;
1162 #pragma mark *** DSA Algorithm Parameters encode/decode ***
1164 CSSM_RETURN
DSAEncodeAlgParams(
1165 NSS_DSAAlgParams
&algParams
,
1166 CssmOwnedData
&encodedParams
)
1168 PRErrorCode prtn
= SecNssEncodeItemOdata(&algParams
,
1169 NSS_DSAAlgParamsTemplate
, encodedParams
);
1171 return CSSMERR_CSP_MEMORY_ERROR
;
1176 CSSM_RETURN
DSADecodeAlgParams(
1177 NSS_DSAAlgParams
&algParams
,
1183 memset(&algParams
, 0, sizeof(algParams
));
1184 PRErrorCode perr
= coder
.decode(p
, len
,
1185 NSS_DSAAlgParamsTemplate
, &algParams
);
1187 logAsnErr("decode(DSAAlgParams)", perr
);
1188 return CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS
;
1194 #pragma mark *** Diffie-Hellman key encode/decode ***
1196 CSSM_RETURN
DHPrivateKeyDecodePKCS3(
1202 NSS_DHPrivateKey nssPrivKey
;
1205 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
1206 perr
= coder
.decode(p
, length
, NSS_DHPrivateKeyTemplate
, &nssPrivKey
);
1208 logAsnErr("decode(DHPrivateKey)", perr
);
1209 return CSSMERR_CSP_INVALID_KEY
;
1212 /* verify alg identifier */
1213 const CSSM_OID
*oid
= &nssPrivKey
.dhOid
;
1214 if(!cspCompareCssmData(oid
, &CSSMOID_DH
)) {
1215 sslAsn1Debug("DHPrivateKeyDecode: bad OID");
1216 return CSSMERR_CSP_ALGID_MISMATCH
;
1219 NSS_DHParameter
¶ms
= nssPrivKey
.params
;
1222 openKey
->priv_key
= cssmDataToBn(nssPrivKey
.secretPart
);
1223 openKey
->p
= cssmDataToBn(params
.prime
);
1224 openKey
->g
= cssmDataToBn(params
.base
);
1225 /* TBD - ignore privateValueLength for now */
1228 /* FIXME - bad sig? memory? */
1229 return CSSMERR_CSP_MEMORY_ERROR
;
1234 CSSM_RETURN
DHPrivateKeyEncodePKCS3(
1237 CssmOwnedData
&encodedKey
)
1239 /* convert into a NSS_DHPrivateKey */
1240 NSS_DHPrivateKey nssPrivKey
;
1241 NSS_DHParameter
¶ms
= nssPrivKey
.params
;
1242 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
1243 nssPrivKey
.dhOid
= CSSMOID_DH
;
1247 bnToCssmData(openKey
->priv_key
, nssPrivKey
.secretPart
, coder
);
1248 bnToCssmData(openKey
->p
, params
.prime
, coder
);
1249 bnToCssmData(openKey
->g
, params
.base
, coder
);
1250 if(openKey
->length
) {
1251 /* actually currently not supported in openssl... */
1252 intToCssmData(openKey
->length
, params
.privateValueLength
, coder
);
1256 return CSSMERR_CSP_MEMORY_ERROR
;
1261 perr
= SecNssEncodeItemOdata(&nssPrivKey
, NSS_DHPrivateKeyTemplate
,
1264 logAsnErr("encode(DHPrivateKey)", perr
);
1265 return CSSMERR_CSP_MEMORY_ERROR
;
1271 * NSS_DHAlgorithmIdentifierX942 <--> DH
1272 * NOTE this is incomplete. It's functional on decode, but we throw
1273 * away everything except p and g. On encode, we put zeroes in
1274 * all the fields we don't deal with. Thus the encode side will NOT be
1275 * interoperable with other implementations.
1277 static void dhToNssAlgIdX942(
1279 NSS_DHAlgorithmIdentifierX942
&algId
,
1283 * When trying to encode a public key in X509 form, we may in
1284 * fact have nothing here - public keys created and exported in
1285 * PKCS3 have the pub_key value, and that's it.
1288 memset(&algId
, 0, sizeof(algId
));
1289 algId
.oid
= CSSMOID_ANSI_DH_PUB_NUMBER
; // not mallocd
1290 NSS_DHDomainParamsX942
¶ms
= algId
.params
;
1292 CSSM_DATA czero
= {1, &zero
};
1293 if(openKey
->p
!= NULL
) {
1294 bnToCssmData(openKey
->p
, params
.p
, coder
);
1297 coder
.allocCopyItem(czero
, params
.p
);
1299 if(openKey
->g
!= NULL
) {
1300 bnToCssmData(openKey
->g
, params
.g
, coder
);
1303 coder
.allocCopyItem(czero
, params
.g
);
1305 /* and we never have a vali0d q */
1306 coder
.allocCopyItem(czero
, params
.q
);
1310 static CSSM_RETURN
nssAlgIdToDhX942(
1311 NSS_DHAlgorithmIdentifierX942
&algId
,
1314 if(!cspCompareCssmData(&algId
.oid
, &CSSMOID_ANSI_DH_PUB_NUMBER
)) {
1315 sslAsn1Debug("nssAlgIdToDhX942: bad OID");
1316 return CSSMERR_CSP_INVALID_KEY
;
1318 openKey
->p
= cssmDataToBn(algId
.params
.p
);
1319 openKey
->g
= cssmDataToBn(algId
.params
.g
);
1323 CSSM_RETURN
DHPrivateKeyDecodePKCS8(
1329 NSS_DHPrivateKeyPKCS8 nssPrivKey
;
1332 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
1333 perr
= coder
.decode(p
, length
, NSS_DHPrivateKeyPKCS8Template
,
1336 logAsnErr("decode(DHPrivateKeyPKCS8)", perr
);
1337 return CSSMERR_CSP_INVALID_KEY
;
1341 CSSM_RETURN crtn
= nssAlgIdToDhX942(nssPrivKey
.algorithm
, openKey
);
1346 /* post-decode private key is a DER encoded integer */
1347 CSSM_DATA privKeyInt
= {0, NULL
};
1348 if(coder
.decodeItem(nssPrivKey
.privateKey
,
1349 SEC_UnsignedIntegerTemplate
,
1351 logAsnErr("decode(DHPrivateKeyPKCS8 privKey int)", perr
);
1352 return CSSMERR_CSP_INVALID_KEY
;
1355 openKey
->priv_key
= cssmDataToBn(privKeyInt
);
1358 /* FIXME - bad sig? memory? */
1359 return CSSMERR_CSP_MEMORY_ERROR
;
1364 CSSM_RETURN
DHPrivateKeyEncodePKCS8(
1367 CssmOwnedData
&encodedKey
)
1369 /* convert into a NSS_DHPrivateKeyPKCS8 */
1370 NSS_DHPrivateKeyPKCS8 nssPrivKey
;
1371 memset(&nssPrivKey
, 0, sizeof(nssPrivKey
));
1373 nssPrivKey
.version
.Length
= 1;
1374 nssPrivKey
.version
.Data
= &vers
;
1375 NSS_DHAlgorithmIdentifierX942
&alg
= nssPrivKey
.algorithm
;
1379 dhToNssAlgIdX942(openKey
, alg
, coder
);
1380 /* pre-encode, nssPrivKey.privateKey is the DER-encoding of
1381 * an ASN integer... */
1382 CSSM_DATA privKeyInt
;
1383 bnToCssmData(openKey
->priv_key
, privKeyInt
, coder
);
1385 /* DER encode the privateKey portion into arena pool memory
1386 * into nssPrivKey.privateKey */
1387 coder
.encodeItem(&privKeyInt
, SEC_UnsignedIntegerTemplate
,
1388 nssPrivKey
.privateKey
);
1391 return CSSMERR_CSP_MEMORY_ERROR
;
1396 perr
= SecNssEncodeItemOdata(&nssPrivKey
, NSS_DHPrivateKeyPKCS8Template
,
1399 logAsnErr("encode(DHPrivateKey)", perr
);
1400 return CSSMERR_CSP_MEMORY_ERROR
;
1406 * In the PKCS3 form, the public blob is simply the literal
1407 * public key value, not DER encoded.
1409 static CSSM_RETURN
DHPublicKeyDecodePKCS3(
1416 CSSM_DATA pubKey
= {(uint32
)length
, (uint8
*)p
};
1417 openKey
->pub_key
= cssmDataToBn(pubKey
);
1421 return CSSMERR_CSP_MEMORY_ERROR
;
1425 static CSSM_RETURN
DHPublicKeyEncodePKCS3(
1428 CssmOwnedData
&encodedKey
)
1432 bnToCssmData(openKey
->pub_key
, pubKey
, coder
);
1433 encodedKey
.copy(CssmData::overlay(pubKey
));
1437 return CSSMERR_CSP_MEMORY_ERROR
;
1441 static CSSM_RETURN
DHPublicKeyDecodeX509(
1447 NSS_DHPublicKeyX509 nssPubKey
;
1450 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
1451 perr
= coder
.decode(p
, length
, NSS_DHPublicKeyX509Template
,
1454 logAsnErr("decode(DHPublicKeyX509)", perr
);
1455 return CSSMERR_CSP_INVALID_KEY
;
1459 CSSM_RETURN crtn
= nssAlgIdToDhX942(nssPubKey
.algorithm
, openKey
);
1465 * Post-decode public key length in bits
1466 * Contents are pub_key as DER-encoded INTEGER
1468 CSSM_DATA
&pubKey
= nssPubKey
.publicKey
;
1469 pubKey
.Length
= (pubKey
.Length
+ 7) / 8;
1470 CSSM_DATA pubKeyInt
= {0, NULL
};
1471 if(coder
.decodeItem(pubKey
,
1472 SEC_UnsignedIntegerTemplate
, &pubKeyInt
)) {
1473 logAsnErr("decode(DHPublicKeyX509 pub key int)", perr
);
1474 return CSSMERR_CSP_INVALID_KEY
;
1476 openKey
->pub_key
= cssmDataToBn(pubKeyInt
);
1479 /* FIXME - bad sig? memory? */
1480 return CSSMERR_CSP_MEMORY_ERROR
;
1485 static CSSM_RETURN
DHPublicKeyEncodeX509(
1488 CssmOwnedData
&encodedKey
)
1490 /* convert into a NSS_DHPublicKeyX509 */
1491 NSS_DHPublicKeyX509 nssPubKey
;
1492 memset(&nssPubKey
, 0, sizeof(nssPubKey
));
1493 NSS_DHAlgorithmIdentifierX942
&alg
= nssPubKey
.algorithm
;
1496 dhToNssAlgIdX942(openKey
, alg
, coder
);
1498 /* encode pub_key as integer */
1499 CSSM_DATA pubKeyInt
= {0, NULL
};
1500 bnToCssmData(openKey
->pub_key
, pubKeyInt
, coder
);
1501 coder
.encodeItem(&pubKeyInt
, SEC_UnsignedIntegerTemplate
,
1502 nssPubKey
.publicKey
);
1503 /* specify length in bits */
1504 nssPubKey
.publicKey
.Length
*= 8;
1507 return CSSMERR_CSP_MEMORY_ERROR
;
1512 perr
= SecNssEncodeItemOdata(&nssPubKey
, NSS_DHPublicKeyX509Template
,
1515 logAsnErr("encode(DHPublicKeyX509)", perr
);
1516 return CSSMERR_CSP_MEMORY_ERROR
;
1521 CSSM_RETURN
DHPrivateKeyDecode(
1523 CSSM_KEYBLOB_FORMAT format
,
1530 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3
:
1531 return DHPrivateKeyDecodePKCS3(coder
, openKey
, p
, length
);
1532 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
:
1533 return DHPrivateKeyDecodePKCS8(coder
, openKey
, p
, length
);
1536 return CSSMERR_CSP_INTERNAL_ERROR
;
1540 CSSM_RETURN
DHPrivateKeyEncode(
1542 CSSM_KEYBLOB_FORMAT format
,
1543 CssmOwnedData
&encodedKey
)
1548 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3
:
1549 return DHPrivateKeyEncodePKCS3(coder
, openKey
, encodedKey
);
1550 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
:
1551 return DHPrivateKeyEncodePKCS8(coder
, openKey
, encodedKey
);
1554 return CSSMERR_CSP_INTERNAL_ERROR
;
1558 CSSM_RETURN
DHPublicKeyDecode(
1560 CSSM_KEYBLOB_FORMAT format
,
1567 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3
:
1568 return DHPublicKeyDecodePKCS3(openKey
, coder
, p
, length
);
1569 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
1570 return DHPublicKeyDecodeX509(openKey
, coder
, p
, length
);
1573 return CSSMERR_CSP_INTERNAL_ERROR
;
1577 CSSM_RETURN
DHPublicKeyEncode(
1579 CSSM_KEYBLOB_FORMAT format
,
1580 CssmOwnedData
&encodedKey
)
1585 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3
:
1586 return DHPublicKeyEncodePKCS3(openKey
, coder
, encodedKey
);
1587 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
1588 return DHPublicKeyEncodeX509(openKey
, coder
, encodedKey
);
1591 return CSSMERR_CSP_INTERNAL_ERROR
;
1596 * Encode/decode a NSS_DHParameterBlock.
1598 CSSM_RETURN
DHParamBlockDecode(
1599 const CSSM_DATA
&encParam
,
1600 NSS_DHParameterBlock
¶mBlock
,
1605 memset(¶mBlock
, 0, sizeof(paramBlock
));
1606 perr
= coder
.decodeItem(encParam
, NSS_DHParameterBlockTemplate
,
1613 * CDSA Extension: the CDSA Algorithm Guide says that the D-H
1614 * parameter block is supposed to be wrapped with its accompanying
1615 * OID. However Openssl does not do this; it just exports
1616 * an encoded DHParameter rather than a DHParameterBlock.
1617 * For compatibility we'll try decoding the parameters as one
1620 memset(¶mBlock
, 0, sizeof(paramBlock
));
1621 perr
= coder
.decodeItem(encParam
, NSS_DHParameterTemplate
,
1622 ¶mBlock
.params
);
1626 return CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS
;
1630 #pragma mark *** Message Digest ***
1633 * Given a message digest and associated algorithm, cook up a PKCS1-style
1634 * DigestInfo and return its DER encoding. This is a necessary step for
1635 * RSA signature (both generating and verifying) - the output of this
1636 * routine is what gets encrypted during signing, and what is expected when
1637 * verifying (i.e., decrypting the signature).
1639 * A good guess for the length of the output digestInfo is the size of the
1640 * key being used to sign/verify. The digest can never be larger than that.
1642 CSSM_RETURN
generateDigestInfo(
1643 const void *msgDigest
,
1645 CSSM_ALGORITHMS digestAlg
, // CSSM_ALGID_SHA1, etc.
1646 CssmOwnedData
&encodedInfo
,
1647 size_t maxEncodedSize
)
1649 if(digestAlg
== CSSM_ALGID_NONE
) {
1650 /* special case, no encode, just copy */
1651 encodedInfo
.copy(msgDigest
, digestLen
);
1655 NSS_DigestInfo digestInfo
;
1656 CSSM_X509_ALGORITHM_IDENTIFIER
&algId
= digestInfo
.digestAlgorithm
;
1658 memset(&digestInfo
, 0, sizeof(digestInfo
));
1660 case CSSM_ALGID_MD5
:
1661 algId
.algorithm
= CSSMOID_MD5
;
1663 case CSSM_ALGID_MD2
:
1664 algId
.algorithm
= CSSMOID_MD2
;
1666 case CSSM_ALGID_SHA1
:
1667 algId
.algorithm
= CSSMOID_SHA1
;
1670 return CSSMERR_CSP_INVALID_ALGORITHM
;
1672 nullAlgParams(algId
);
1673 digestInfo
.digest
.Data
= (uint8
*)msgDigest
;
1674 digestInfo
.digest
.Length
= digestLen
;
1678 perr
= SecNssEncodeItemOdata(&digestInfo
, NSS_DigestInfoTemplate
,
1681 logAsnErr("encode(digestInfo)", perr
);
1682 return CSSMERR_CSP_MEMORY_ERROR
;