pk11kea.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:8k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. /*
  34.  * This file implements the Symkey wrapper and the PKCS context
  35.  * Interfaces.
  36.  */
  37. #include "seccomon.h"
  38. #include "secmod.h"
  39. #include "prlock.h"
  40. #include "secmodi.h"
  41. #include "pkcs11.h"
  42. #include "pk11func.h"
  43. #include "secitem.h"
  44. #include "key.h"
  45. #include "secasn1.h"
  46. #include "sechash.h"
  47. #include "cert.h"
  48. #include "secerr.h"
  49. /*
  50.  * find an RSA public key on a card
  51.  */
  52. static CK_OBJECT_HANDLE
  53. pk11_FindRSAPubKey(PK11SlotInfo *slot)
  54. {
  55.     CK_KEY_TYPE key_type = CKK_RSA;
  56.     CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY;
  57.     CK_ATTRIBUTE theTemplate[2];
  58.     int template_count = sizeof(theTemplate)/sizeof(theTemplate[0]);
  59.     CK_ATTRIBUTE *attrs = theTemplate;
  60.     PK11_SETATTRS(attrs,CKA_CLASS,&class_type,sizeof(class_type)); attrs++;
  61.     PK11_SETATTRS(attrs,CKA_KEY_TYPE,&key_type,sizeof(key_type)); attrs++;
  62.     template_count = attrs - theTemplate;
  63.     PR_ASSERT(template_count <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));
  64.     return pk11_FindObjectByTemplate(slot,theTemplate,template_count);
  65. }
  66. SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType,
  67.  CK_OBJECT_HANDLE id);
  68. PK11SymKey *
  69. pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
  70.   CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey)
  71. {
  72.     PK11SymKey *newSymKey = NULL;
  73.     SECStatus rv;
  74.     /* performance improvement can go here --- use a generated key to as a
  75.      * per startup wrapping key. If it exists, use it, otherwise do a full
  76.      * key exchange. */
  77.     /* find a common Key Exchange algorithm */
  78.     /* RSA */
  79.     if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) && 
  80. PK11_DoesMechanism(slot,CKM_RSA_PKCS)) {
  81. CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_KEY;
  82. CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_KEY;
  83. SECKEYPublicKey *pubKey = NULL;
  84. SECKEYPrivateKey *privKey = NULL;
  85. SECItem wrapData;
  86. wrapData.data = NULL;
  87. /* find RSA Public Key on target */
  88. pubKeyHandle = pk11_FindRSAPubKey(slot);
  89. if (pubKeyHandle != CK_INVALID_KEY) {
  90.     privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY);
  91. }
  92. /* if no key exits, generate a key pair */
  93. if (privKeyHandle == CK_INVALID_KEY) {
  94.     unsigned int     keyLength = PK11_GetKeyLength(symKey);
  95.     PK11RSAGenParams rsaParams;
  96.     rsaParams.keySizeInBits = 
  97. ((keyLength == 0) || (keyLength > 16)) ? 512 : 256;
  98.     rsaParams.pe  = 0x10001;
  99.     privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN, 
  100. &rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx);
  101. } else {
  102.     /* if key's exist, build SECKEY data structures for them */
  103.     privKey = PK11_MakePrivKey(slot,nullKey, PR_TRUE, privKeyHandle,
  104. symKey->cx);
  105.     if (privKey != NULL) {
  106.      pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle);
  107. if (pubKey && pubKey->pkcs11Slot) {
  108.     PK11_FreeSlot(pubKey->pkcs11Slot);
  109.     pubKey->pkcs11Slot = NULL;
  110.     pubKey->pkcs11ID = CK_INVALID_KEY;
  111. }
  112.     }
  113. }
  114. if (privKey == NULL) goto rsa_failed;
  115. if (pubKey == NULL)  goto rsa_failed;
  116.         wrapData.len  = SECKEY_PublicKeyStrength(pubKey);
  117.         if (!wrapData.len) goto rsa_failed;
  118.         wrapData.data = PORT_Alloc(wrapData.len);
  119.         if (wrapData.data == NULL) goto rsa_failed;
  120. /* now wrap the keys in and out */
  121. rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData);
  122. if (rv == SECSuccess) {
  123.     newSymKey = PK11_PubUnwrapSymKey(privKey,&wrapData,type,operation,
  124. symKey->size);
  125. }
  126. rsa_failed:
  127. if (wrapData.data != NULL) PORT_Free(wrapData.data);
  128. if (privKey != NULL) SECKEY_DestroyPrivateKey(privKey);
  129. if (pubKey != NULL) SECKEY_DestroyPublicKey(pubKey);
  130. return  newSymKey;
  131.     }
  132.     /* KEA */
  133.     if (PK11_DoesMechanism(symKey->slot, CKM_KEA_KEY_DERIVE) && 
  134. PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) {
  135. CERTCertificate *certSource = NULL;
  136. CERTCertificate *certTarget = NULL;
  137. SECKEYPublicKey *pubKeySource = NULL;
  138. SECKEYPublicKey *pubKeyTarget = NULL;
  139. SECKEYPrivateKey *privKeySource = NULL;
  140. SECKEYPrivateKey *privKeyTarget = NULL;
  141. PK11SymKey *tekSource = NULL;
  142. PK11SymKey *tekTarget = NULL;
  143. SECItem Ra,wrap;
  144. /* can only exchange skipjack keys */
  145. if (type != CKM_SKIPJACK_CBC64) {
  146.          PORT_SetError( SEC_ERROR_NO_MODULE );
  147.     goto kea_failed;
  148. }
  149. /* find a pair of certs we can use */
  150. rv = PK11_GetKEAMatchedCerts(symKey->slot,slot,&certSource,&certTarget);
  151. if (rv != SECSuccess) goto kea_failed;
  152. /* get all the key pairs */
  153. pubKeyTarget = CERT_ExtractPublicKey(certSource);
  154. pubKeySource = CERT_ExtractPublicKey(certTarget);
  155. privKeySource = 
  156. PK11_FindKeyByDERCert(symKey->slot,certSource,symKey->cx);
  157. privKeyTarget = 
  158. PK11_FindKeyByDERCert(slot,certTarget,symKey->cx);
  159. if ((pubKeySource == NULL) || (pubKeyTarget == NULL) ||
  160.   (privKeySource == NULL) || (privKeyTarget == NULL)) goto kea_failed;
  161. /* generate the wrapping TEK's */
  162. Ra.data = (unsigned char*)PORT_Alloc(128 /* FORTEZZA RA MAGIC */);
  163. Ra.len = 128;
  164. if (Ra.data == NULL) goto kea_failed;
  165. tekSource = PK11_PubDerive(privKeySource,pubKeyTarget,PR_TRUE,&Ra,NULL,
  166. CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx);
  167. tekTarget = PK11_PubDerive(privKeyTarget,pubKeySource,PR_FALSE,&Ra,NULL,
  168. CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx);
  169. PORT_Free(Ra.data);
  170. if ((tekSource == NULL) || (tekTarget == NULL)) { goto kea_failed; }
  171. /* wrap the key out of Source into target */
  172. wrap.data = (unsigned char*)PORT_Alloc(12); /* MAGIC SKIPJACK LEN */
  173. wrap.len = 12;
  174. /* paranoia to prevent infinite recursion on bugs */
  175. PORT_Assert(tekSource->slot == symKey->slot);
  176. if (tekSource->slot != symKey->slot) {
  177.          PORT_SetError( SEC_ERROR_NO_MODULE );
  178.     goto kea_failed;
  179. }
  180. rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap);
  181. if (rv == SECSuccess) {
  182.     newSymKey = PK11_UnwrapSymKey(tekTarget, CKM_SKIPJACK_WRAP, NULL,
  183. &wrap, type, operation, symKey->size);
  184. }
  185. PORT_Free(wrap.data);
  186. kea_failed:
  187. if (certSource == NULL) CERT_DestroyCertificate(certSource);
  188. if (certTarget == NULL) CERT_DestroyCertificate(certTarget);
  189. if (pubKeySource == NULL) SECKEY_DestroyPublicKey(pubKeySource);
  190. if (pubKeyTarget == NULL) SECKEY_DestroyPublicKey(pubKeyTarget);
  191. if (privKeySource == NULL) SECKEY_DestroyPrivateKey(privKeySource);
  192. if (privKeyTarget == NULL) SECKEY_DestroyPrivateKey(privKeyTarget);
  193. if (tekSource == NULL) PK11_FreeSymKey(tekSource);
  194. if (tekTarget == NULL) PK11_FreeSymKey(tekTarget);
  195. return newSymKey;
  196.     }
  197.     PORT_SetError( SEC_ERROR_NO_MODULE );
  198.     return NULL;
  199. }