BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file nsskey.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * Function for opening a NSS certificate and its private key.
32 */
33  
34 #ifndef BADVPN_MISC_NSSKEY_H
35 #define BADVPN_MISC_NSSKEY_H
36  
37 #include <stdlib.h>
38  
39 #include <prerror.h>
40 #include <nss/cert.h>
41 #include <nss/keyhi.h>
42 #include <nss/pk11func.h>
43  
44 #include <base/BLog.h>
45  
46 #include <generated/blog_channel_nsskey.h>
47  
48 /**
49 * Opens a NSS certificate and its private key.
50 *
51 * @param name name of the certificate
52 * @param out_cert on success, the certificate will be returned here. Should be
53 * released with CERT_DestroyCertificate.
54 * @param out_key on success, the private key will be returned here. Should be
55 * released with SECKEY_DestroyPrivateKey.
56 * @return 1 on success, 0 on failure
57 */
58 static int open_nss_cert_and_key (char *name, CERTCertificate **out_cert, SECKEYPrivateKey **out_key) WARN_UNUSED;
59  
60 static SECKEYPrivateKey * find_nss_private_key (char *name)
61 {
62 SECKEYPrivateKey *key = NULL;
63  
64 PK11SlotList *slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
65 if (!slot_list) {
66 return NULL;
67 }
68  
69 PK11SlotListElement *slot_entry;
70 for (slot_entry = slot_list->head; !key && slot_entry; slot_entry = slot_entry->next) {
71 SECKEYPrivateKeyList *key_list = PK11_ListPrivKeysInSlot(slot_entry->slot, name, NULL);
72 if (!key_list) {
73 BLog(BLOG_ERROR, "PK11_ListPrivKeysInSlot failed");
74 continue;
75 }
76  
77 SECKEYPrivateKeyListNode *key_node;
78 for (key_node = PRIVKEY_LIST_HEAD(key_list); !key && !PRIVKEY_LIST_END(key_node, key_list); key_node = PRIVKEY_LIST_NEXT(key_node)) {
79 char *key_name = PK11_GetPrivateKeyNickname(key_node->key);
80 if (!key_name || strcmp(key_name, name)) {
81 PORT_Free((void *)key_name);
82 continue;
83 }
84 PORT_Free((void *)key_name);
85  
86 key = SECKEY_CopyPrivateKey(key_node->key);
87 }
88  
89 SECKEY_DestroyPrivateKeyList(key_list);
90 }
91  
92 PK11_FreeSlotList(slot_list);
93  
94 return key;
95 }
96  
97 int open_nss_cert_and_key (char *name, CERTCertificate **out_cert, SECKEYPrivateKey **out_key)
98 {
99 CERTCertificate *cert;
100 cert = CERT_FindCertByNicknameOrEmailAddr(CERT_GetDefaultCertDB(), name);
101 if (!cert) {
102 BLog(BLOG_ERROR, "CERT_FindCertByName failed (%d)", (int)PR_GetError());
103 return 0;
104 }
105  
106 SECKEYPrivateKey *key = find_nss_private_key(name);
107 if (!key) {
108 BLog(BLOG_ERROR, "Failed to find private key");
109 CERT_DestroyCertificate(cert);
110 return 0;
111 }
112  
113 *out_cert = cert;
114 *out_key = key;
115 return 1;
116 }
117  
118 #endif