Change all our uses of CRYPTO_THREAD_run_once to use RUN_ONCE instead
[openssl.git] / crypto / engine / eng_pkey.c
1 /*
2  * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include "eng_int.h"
11
12 /* Basic get/set stuff */
13
14 int ENGINE_set_load_privkey_function(ENGINE *e,
15                                      ENGINE_LOAD_KEY_PTR loadpriv_f)
16 {
17     e->load_privkey = loadpriv_f;
18     return 1;
19 }
20
21 int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
22 {
23     e->load_pubkey = loadpub_f;
24     return 1;
25 }
26
27 int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
28                                              ENGINE_SSL_CLIENT_CERT_PTR
29                                              loadssl_f)
30 {
31     e->load_ssl_client_cert = loadssl_f;
32     return 1;
33 }
34
35 ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
36 {
37     return e->load_privkey;
38 }
39
40 ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
41 {
42     return e->load_pubkey;
43 }
44
45 ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
46                                                                *e)
47 {
48     return e->load_ssl_client_cert;
49 }
50
51 /* API functions to load public/private keys */
52
53 EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
54                                   UI_METHOD *ui_method, void *callback_data)
55 {
56     EVP_PKEY *pkey;
57
58     if (e == NULL) {
59         ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
60                   ERR_R_PASSED_NULL_PARAMETER);
61         return 0;
62     }
63     CRYPTO_THREAD_write_lock(global_engine_lock);
64     if (e->funct_ref == 0) {
65         CRYPTO_THREAD_unlock(global_engine_lock);
66         ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED);
67         return 0;
68     }
69     CRYPTO_THREAD_unlock(global_engine_lock);
70     if (!e->load_privkey) {
71         ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
72                   ENGINE_R_NO_LOAD_FUNCTION);
73         return 0;
74     }
75     pkey = e->load_privkey(e, key_id, ui_method, callback_data);
76     if (!pkey) {
77         ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
78                   ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
79         return 0;
80     }
81     return pkey;
82 }
83
84 EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
85                                  UI_METHOD *ui_method, void *callback_data)
86 {
87     EVP_PKEY *pkey;
88
89     if (e == NULL) {
90         ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
91                   ERR_R_PASSED_NULL_PARAMETER);
92         return 0;
93     }
94     CRYPTO_THREAD_write_lock(global_engine_lock);
95     if (e->funct_ref == 0) {
96         CRYPTO_THREAD_unlock(global_engine_lock);
97         ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED);
98         return 0;
99     }
100     CRYPTO_THREAD_unlock(global_engine_lock);
101     if (!e->load_pubkey) {
102         ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION);
103         return 0;
104     }
105     pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
106     if (!pkey) {
107         ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
108                   ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
109         return 0;
110     }
111     return pkey;
112 }
113
114 int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
115                                 STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
116                                 EVP_PKEY **ppkey, STACK_OF(X509) **pother,
117                                 UI_METHOD *ui_method, void *callback_data)
118 {
119
120     if (e == NULL) {
121         ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
122                   ERR_R_PASSED_NULL_PARAMETER);
123         return 0;
124     }
125     CRYPTO_THREAD_write_lock(global_engine_lock);
126     if (e->funct_ref == 0) {
127         CRYPTO_THREAD_unlock(global_engine_lock);
128         ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
129                   ENGINE_R_NOT_INITIALISED);
130         return 0;
131     }
132     CRYPTO_THREAD_unlock(global_engine_lock);
133     if (!e->load_ssl_client_cert) {
134         ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
135                   ENGINE_R_NO_LOAD_FUNCTION);
136         return 0;
137     }
138     return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
139                                    ui_method, callback_data);
140 }