Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/pk11wrap/pk11kea.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 /* | |
5 * This file implements the Symkey wrapper and the PKCS context | |
6 * Interfaces. | |
7 */ | |
8 | |
9 #include "seccomon.h" | |
10 #include "secmod.h" | |
11 #include "nssilock.h" | |
12 #include "secmodi.h" | |
13 #include "secmodti.h" | |
14 #include "pkcs11.h" | |
15 #include "pk11func.h" | |
16 #include "secitem.h" | |
17 #include "key.h" | |
18 #include "secasn1.h" | |
19 #include "sechash.h" | |
20 #include "cert.h" | |
21 #include "secerr.h" | |
22 | |
23 /* | |
24 * find an RSA public key on a card | |
25 */ | |
26 static CK_OBJECT_HANDLE | |
27 pk11_FindRSAPubKey(PK11SlotInfo *slot) | |
28 { | |
29 CK_KEY_TYPE key_type = CKK_RSA; | |
30 CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY; | |
31 CK_ATTRIBUTE theTemplate[2]; | |
32 int template_count = sizeof(theTemplate)/sizeof(theTemplate[0]); | |
33 CK_ATTRIBUTE *attrs = theTemplate; | |
34 | |
35 PK11_SETATTRS(attrs,CKA_CLASS,&class_type,sizeof(class_type)); attrs++; | |
36 PK11_SETATTRS(attrs,CKA_KEY_TYPE,&key_type,sizeof(key_type)); attrs++; | |
37 template_count = attrs - theTemplate; | |
38 PR_ASSERT(template_count <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)); | |
39 | |
40 return pk11_FindObjectByTemplate(slot,theTemplate,template_count); | |
41 } | |
42 | |
43 PK11SymKey * | |
44 pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, | |
45 CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, | |
46 PRBool isPerm, PK11SymKey *symKey) | |
47 { | |
48 PK11SymKey *newSymKey = NULL; | |
49 SECStatus rv; | |
50 /* performance improvement can go here --- use a generated key at startup | |
51 * to generate a per token wrapping key. If it exists, use it, otherwise | |
52 * do a full key exchange. */ | |
53 | |
54 /* find a common Key Exchange algorithm */ | |
55 /* RSA */ | |
56 if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) && | |
57 PK11_DoesMechanism(slot,CKM_RSA_PKCS)) { | |
58 CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_HANDLE; | |
59 CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE; | |
60 SECKEYPublicKey *pubKey = NULL; | |
61 SECKEYPrivateKey *privKey = NULL; | |
62 SECItem wrapData; | |
63 unsigned int symKeyLength = PK11_GetKeyLength(symKey); | |
64 | |
65 wrapData.data = NULL; | |
66 | |
67 /* find RSA Public Key on target */ | |
68 pubKeyHandle = pk11_FindRSAPubKey(slot); | |
69 if (pubKeyHandle != CK_INVALID_HANDLE) { | |
70 privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY); | |
71 } | |
72 | |
73 /* if no key exists, generate a key pair */ | |
74 if (privKeyHandle == CK_INVALID_HANDLE) { | |
75 PK11RSAGenParams rsaParams; | |
76 | |
77 if (symKeyLength > 53) /* bytes */ { | |
78 /* we'd have to generate an RSA key pair > 512 bits long, | |
79 ** and that's too costly. Don't even try. | |
80 */ | |
81 PORT_SetError( SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY ); | |
82 goto rsa_failed; | |
83 } | |
84 rsaParams.keySizeInBits = | |
85 (symKeyLength > 21 || symKeyLength == 0) ? 512 : 256; | |
86 rsaParams.pe = 0x10001; | |
87 privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN, | |
88 &rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx); | |
89 } else { | |
90 /* if keys exist, build SECKEY data structures for them */ | |
91 privKey = PK11_MakePrivKey(slot,nullKey, PR_TRUE, privKeyHandle, | |
92 symKey->cx); | |
93 if (privKey != NULL) { | |
94 pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle); | |
95 if (pubKey && pubKey->pkcs11Slot) { | |
96 PK11_FreeSlot(pubKey->pkcs11Slot); | |
97 pubKey->pkcs11Slot = NULL; | |
98 pubKey->pkcs11ID = CK_INVALID_HANDLE; | |
99 } | |
100 } | |
101 } | |
102 if (privKey == NULL) goto rsa_failed; | |
103 if (pubKey == NULL) goto rsa_failed; | |
104 | |
105 wrapData.len = SECKEY_PublicKeyStrength(pubKey); | |
106 if (!wrapData.len) goto rsa_failed; | |
107 wrapData.data = PORT_Alloc(wrapData.len); | |
108 if (wrapData.data == NULL) goto rsa_failed; | |
109 | |
110 /* now wrap the keys in and out */ | |
111 rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData); | |
112 if (rv == SECSuccess) { | |
113 newSymKey = PK11_PubUnwrapSymKeyWithFlagsPerm(privKey, | |
114 &wrapData,type,operation,symKeyLength,flags,isPerm); | |
115 /* make sure we wound up where we wanted to be! */ | |
116 if (newSymKey && newSymKey->slot != slot) { | |
117 PK11_FreeSymKey(newSymKey); | |
118 newSymKey = NULL; | |
119 } | |
120 } | |
121 rsa_failed: | |
122 if (wrapData.data != NULL) PORT_Free(wrapData.data); | |
123 if (privKey != NULL) SECKEY_DestroyPrivateKey(privKey); | |
124 if (pubKey != NULL) SECKEY_DestroyPublicKey(pubKey); | |
125 | |
126 return newSymKey; | |
127 } | |
128 PORT_SetError( SEC_ERROR_NO_MODULE ); | |
129 return NULL; | |
130 } | |
131 |