2 * Copyright (c) 2000-2001,2011-2012,2014 Apple 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.
25 #include <opensslUtils/opensslAsn1.h>
26 #include <security_utilities/logging.h>
27 #include <security_utilities/debugging.h>
28 #include <opensslUtils/opensslUtils.h>
29 #include <openssl/bn.h>
30 #include <openssl/dh.h>
31 #include <openssl/err.h>
33 #define dhMiscDebug(args...) secdebug("dhMisc", ## args)
37 * -- obtain CSSM key with specified attr (there must only be one)
38 * -- validate keyClass per caller's specification
39 * -- validate keyUsage
40 * -- convert to DH *, allocating the DH key if necessary
43 const Context
&context
,
44 AppleCSPSession
&session
,
45 CSSM_ATTRIBUTE_TYPE attr
, // CSSM_ATTRIBUTE_KEY for private key
46 // CSSM_ATTRIBUTE_PUBLIC_KEY for public key
47 CSSM_KEYCLASS keyClass
, // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
48 CSSM_KEYUSE usage
, // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
49 bool &mallocdKey
) // RETURNED
51 CssmKey
*cssmKey
= context
.get
<CssmKey
>(attr
);
55 const CSSM_KEYHEADER
&hdr
= cssmKey
->KeyHeader
;
56 if(hdr
.AlgorithmId
!= CSSM_ALGID_DH
) {
57 CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH
);
59 if(hdr
.KeyClass
!= keyClass
) {
60 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS
);
62 cspValidateIntendedKeyUsage(&hdr
, usage
);
63 cspVerifyKeyTimes(hdr
);
64 return cssmKeyToDh(*cssmKey
, session
, mallocdKey
);
68 * Convert a CssmKey to an DH * key. May result in the
69 * creation of a new DH (when cssmKey is a raw key); allocdKey is true
70 * in that case in which case the caller generally has to free the allocd key).
73 const CssmKey
&cssmKey
,
74 AppleCSPSession
&session
,
75 bool &allocdKey
) // RETURNED
80 const CSSM_KEYHEADER
*hdr
= &cssmKey
.KeyHeader
;
81 if(hdr
->AlgorithmId
!= CSSM_ALGID_DH
) {
82 // someone else's key (should never happen)
83 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM
);
85 switch(hdr
->BlobType
) {
86 case CSSM_KEYBLOB_RAW
:
87 dhKey
= rawCssmKeyToDh(cssmKey
);
88 cspDhDebug("cssmKeyToDh, raw, dhKey %p", dhKey
);
91 case CSSM_KEYBLOB_REFERENCE
:
93 BinaryKey
&binKey
= session
.lookupRefKey(cssmKey
);
94 DHBinaryKey
*dhBinKey
= dynamic_cast<DHBinaryKey
*>(&binKey
);
95 /* this cast failing means that this is some other
96 * kind of binary key */
97 if(dhBinKey
== NULL
) {
98 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
100 assert(dhBinKey
->mDhKey
!= NULL
);
101 dhKey
= dhBinKey
->mDhKey
;
102 cspDhDebug("cssmKeyToDh, ref, dhKey %p", dhKey
);
106 CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT
);
112 * Convert a raw CssmKey to a newly alloc'd DH key.
115 const CssmKey
&cssmKey
)
117 const CSSM_KEYHEADER
*hdr
= &cssmKey
.KeyHeader
;
120 if(hdr
->AlgorithmId
!= CSSM_ALGID_DH
) {
121 // someone else's key (should never happen)
122 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM
);
124 assert(hdr
->BlobType
== CSSM_KEYBLOB_RAW
);
125 /* validate and figure out what we're dealing with */
126 switch(hdr
->KeyClass
) {
127 case CSSM_KEYCLASS_PUBLIC_KEY
:
128 switch(hdr
->Format
) {
129 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3
:
130 case CSSM_KEYBLOB_RAW_FORMAT_X509
:
132 /* openssh real soon now */
133 case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH
:
136 CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT
);
140 case CSSM_KEYCLASS_PRIVATE_KEY
:
141 switch(hdr
->Format
) {
142 case CSSM_KEYBLOB_RAW_FORMAT_PKCS3
: // default
143 case CSSM_KEYBLOB_RAW_FORMAT_PKCS8
: // SMIME style
145 /* openssh real soon now */
146 case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH
:
149 CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT
);
154 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS
);
159 DH
*dhKey
= DH_new();
161 crtn
= CSSMERR_CSP_MEMORY_ERROR
;
166 crtn
= DHPublicKeyDecode(dhKey
, hdr
->Format
,
167 cssmKey
.KeyData
.Data
, (unsigned)cssmKey
.KeyData
.Length
);
170 crtn
= DHPrivateKeyDecode(dhKey
, hdr
->Format
,
171 cssmKey
.KeyData
.Data
, (unsigned)cssmKey
.KeyData
.Length
);
180 CssmError::throwMe(crtn
);
182 cspDhDebug("rawCssmKeyToDh, dhKey %p", dhKey
);