xref: /illumos-gate/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h (revision e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9be)
1 /*
2  * COPYRIGHT (C) 2006,2007
3  * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
4  * ALL RIGHTS RESERVED
5  *
6  * Permission is granted to use, copy, create derivative works
7  * and redistribute this software and such derivative works
8  * for any purpose, so long as the name of The University of
9  * Michigan is not used in any advertising or publicity
10  * pertaining to the use of distribution of this software
11  * without specific, written prior authorization.  If the
12  * above copyright notice or any other identification of the
13  * University of Michigan is included in any copy of any
14  * portion of this software, then the disclaimer below must
15  * also be included.
16  *
17  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
24  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGES.
29  */
30 
31 #ifndef _PKINIT_CRYPTO_OPENSSL_H
32 #define _PKINIT_CRYPTO_OPENSSL_H
33 
34 #include <openssl/bn.h>
35 #include <openssl/dh.h>
36 #include <openssl/x509.h>
37 #include <openssl/pkcs7.h>
38 #include <openssl/pkcs12.h>
39 #include <openssl/obj_mac.h>
40 #include <openssl/x509v3.h>
41 #include <openssl/err.h>
42 #include <openssl/evp.h>
43 #include <openssl/asn1_mac.h>
44 #include <openssl/sha.h>
45 #include <openssl/asn1.h>
46 #include <openssl/pem.h>
47 
48 #include "pkinit.h"
49 
50 #define DN_BUF_LEN  256
51 #define MAX_CREDS_ALLOWED 20
52 
53 struct _pkinit_cred_info {
54     X509 *cert;
55     EVP_PKEY *key;
56 #ifndef WITHOUT_PKCS11
57     CK_BYTE_PTR cert_id;
58     int cert_id_len;
59 #endif
60 };
61 typedef struct _pkinit_cred_info * pkinit_cred_info;
62 
63 struct _pkinit_identity_crypto_context {
64     pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
65     STACK_OF(X509) *my_certs;   /* available user certs */
66     int cert_index;             /* cert to use out of available certs*/
67     EVP_PKEY *my_key;           /* available user keys if in filesystem */
68     STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
69     STACK_OF(X509) *intermediateCAs;   /* available intermediate ca certs */
70     STACK_OF(X509_CRL) *revoked;    /* available crls */
71     int pkcs11_method;
72     krb5_prompter_fct prompter;
73     void *prompter_data;
74 #ifndef WITHOUT_PKCS11
75     char *p11_module_name;
76     CK_SLOT_ID slotid;
77     char *token_label;
78     char *cert_label;
79     /* These are crypto-specific */
80     void *p11_module;
81     CK_SESSION_HANDLE session;
82     CK_FUNCTION_LIST_PTR p11;
83     CK_BYTE_PTR cert_id;
84     int cert_id_len;
85     CK_MECHANISM_TYPE mech;
86     /*
87      * Solaris Kerberos:
88      * If PKCS#11 is already being used by the process then C_Finalize should
89      * not be called by pkinit as it would invalidate any PKCS#11 sessions the
90      * process was using prior to loading the pkinit plugin. "finalize_pkcs11"
91      * indicates whether or not C_Finalize should be called by pkinit.
92      */
93     krb5_boolean finalize_pkcs11;
94 #endif
95 };
96 
97 struct _pkinit_plg_crypto_context {
98     DH *dh_1024;
99     DH *dh_2048;
100     DH *dh_4096;
101     ASN1_OBJECT *id_pkinit_authData;
102     ASN1_OBJECT *id_pkinit_authData9;
103     ASN1_OBJECT *id_pkinit_DHKeyData;
104     ASN1_OBJECT *id_pkinit_rkeyData;
105     ASN1_OBJECT *id_pkinit_san;
106     ASN1_OBJECT *id_ms_san_upn;
107     ASN1_OBJECT *id_pkinit_KPClientAuth;
108     ASN1_OBJECT *id_pkinit_KPKdc;
109     ASN1_OBJECT *id_ms_kp_sc_logon;
110     ASN1_OBJECT *id_kp_serverAuth;
111 };
112 
113 struct _pkinit_req_crypto_context {
114     X509 *received_cert;
115     DH *dh;
116 };
117 
118 #define CERT_MAGIC 0x53534c43
119 struct _pkinit_cert_data {
120     unsigned int magic;
121     pkinit_plg_crypto_context plgctx;
122     pkinit_req_crypto_context reqctx;
123     pkinit_identity_crypto_context idctx;
124     pkinit_cred_info cred;
125     unsigned int index;	    /* Index of this cred in the creds[] array */
126 };
127 
128 #define ITER_MAGIC 0x53534c49
129 struct _pkinit_cert_iter_data {
130     unsigned int magic;
131     pkinit_plg_crypto_context plgctx;
132     pkinit_req_crypto_context reqctx;
133     pkinit_identity_crypto_context idctx;
134     unsigned int index;
135 };
136 
137 static void openssl_init(void);
138 
139 static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
140 static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
141 
142 static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context );
143 static void pkinit_fini_dh_params(pkinit_plg_crypto_context );
144 
145 static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx);
146 static void pkinit_fini_certs(pkinit_identity_crypto_context ctx);
147 
148 static krb5_error_code pkinit_init_pkcs11(pkinit_identity_crypto_context ctx);
149 static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx);
150 
151 static krb5_error_code pkinit_encode_dh_params
152 	(BIGNUM *, BIGNUM *, BIGNUM *, unsigned char **, unsigned int *);
153 static DH *pkinit_decode_dh_params
154 	(DH **, unsigned char **, unsigned int );
155 static int pkinit_check_dh_params
156 	(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1);
157 
158 static krb5_error_code pkinit_sign_data
159 	(krb5_context context, pkinit_identity_crypto_context cryptoctx,
160 		unsigned char *data, unsigned int data_len,
161 		unsigned char **sig, unsigned int *sig_len);
162 
163 static krb5_error_code create_signature
164 	(unsigned char **, unsigned int *, unsigned char *, unsigned int,
165 		EVP_PKEY *pkey);
166 
167 static krb5_error_code pkinit_decode_data
168 	(krb5_context context, pkinit_identity_crypto_context cryptoctx,
169 		unsigned char *data, unsigned int data_len,
170 		unsigned char **decoded, unsigned int *decoded_len);
171 
172 static krb5_error_code decode_data
173 	(unsigned char **, unsigned int *, unsigned char *, unsigned int,
174 		EVP_PKEY *pkey, X509 *cert);
175 
176 #ifdef DEBUG_DH
177 static void print_dh(DH *, char *);
178 static void print_pubkey(BIGNUM *, char *);
179 #endif
180 
181 static int prepare_enc_data
182 	(unsigned char *indata, int indata_len, unsigned char **outdata,
183 		int *outdata_len);
184 
185 static int openssl_callback (int, X509_STORE_CTX *);
186 static int openssl_callback_ignore_crls (int, X509_STORE_CTX *);
187 
188 static int pkcs7_decrypt
189 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
190 		PKCS7 *p7, BIO *bio);
191 
192 static BIO * pkcs7_dataDecode
193 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
194 		PKCS7 *p7);
195 
196 static ASN1_OBJECT * pkinit_pkcs7type2oid
197 	(pkinit_plg_crypto_context plg_cryptoctx, int pkcs7_type);
198 
199 static krb5_error_code pkinit_create_sequence_of_principal_identifiers
200 	(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx,
201 		pkinit_req_crypto_context req_cryptoctx,
202 		pkinit_identity_crypto_context id_cryptoctx,
203 		int type, krb5_data **out_data);
204 
205 #ifndef WITHOUT_PKCS11
206 static krb5_error_code pkinit_find_private_key
207 	(pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage,
208 		CK_OBJECT_HANDLE *objp);
209 static krb5_error_code pkinit_login
210 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
211 		CK_TOKEN_INFO *tip);
212 static krb5_error_code pkinit_open_session
213 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx);
214 static void * pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p);
215 static CK_RV pkinit_C_UnloadModule(void *handle);
216 #ifdef SILLYDECRYPT
217 CK_RV pkinit_C_Decrypt
218 	(pkinit_identity_crypto_context id_cryptoctx,
219 		CK_BYTE_PTR pEncryptedData, CK_ULONG  ulEncryptedDataLen,
220 		CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);
221 #endif
222 
223 static krb5_error_code pkinit_sign_data_pkcs11
224 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
225 		unsigned char *data, unsigned int data_len,
226 		unsigned char **sig, unsigned int *sig_len);
227 static krb5_error_code pkinit_decode_data_pkcs11
228 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
229 		unsigned char *data, unsigned int data_len,
230 		unsigned char **decoded_data, unsigned int *decoded_data_len);
231 #endif	/* WITHOUT_PKCS11 */
232 
233 static krb5_error_code pkinit_sign_data_fs
234 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
235 		unsigned char *data, unsigned int data_len,
236 		unsigned char **sig, unsigned int *sig_len);
237 static krb5_error_code pkinit_decode_data_fs
238 	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
239 		unsigned char *data, unsigned int data_len,
240 		unsigned char **decoded_data, unsigned int *decoded_data_len);
241 
242 static krb5_error_code der_decode_data
243 	(unsigned char *, long, unsigned char **, long *);
244 
245 static krb5_error_code
246 create_krb5_invalidCertificates(krb5_context context,
247 				pkinit_plg_crypto_context plg_cryptoctx,
248 				pkinit_req_crypto_context req_cryptoctx,
249 				pkinit_identity_crypto_context id_cryptoctx,
250 				krb5_external_principal_identifier *** ids);
251 
252 static krb5_error_code
253 create_identifiers_from_stack(STACK_OF(X509) *sk,
254 			      krb5_external_principal_identifier *** ids);
255 #ifdef LONGHORN_BETA_COMPAT
256 static int
257 wrap_signeddata(unsigned char *data, unsigned int data_len,
258 		unsigned char **out, unsigned int *out_len,
259 		int is_longhorn_server);
260 #else
261 static int
262 wrap_signeddata(unsigned char *data, unsigned int data_len,
263 		unsigned char **out, unsigned int *out_len);
264 #endif
265 
266 /* This handy macro borrowed from crypto/x509v3/v3_purp.c */
267 #define ku_reject(x, usage) \
268 	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
269 
270 static char *
271 pkinit_pkcs11_code_to_text(int err);
272 
273 #endif	/* _PKINIT_CRYPTO_OPENSSL_H */
274