pkinit_crypto_openssl.h revision 12941:2df46ea8f1b1
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/*
32 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
33 */
34
35#ifndef _PKINIT_CRYPTO_OPENSSL_H
36#define _PKINIT_CRYPTO_OPENSSL_H
37
38#include <openssl/bn.h>
39#include <openssl/dh.h>
40#include <openssl/x509.h>
41#include <openssl/pkcs7.h>
42#include <openssl/pkcs12.h>
43#include <openssl/obj_mac.h>
44#include <openssl/x509v3.h>
45#include <openssl/err.h>
46#include <openssl/evp.h>
47#include <openssl/asn1_mac.h>
48#include <openssl/sha.h>
49#include <openssl/asn1.h>
50#include <openssl/pem.h>
51
52#include "pkinit.h"
53
54#define DN_BUF_LEN  256
55#define MAX_CREDS_ALLOWED 20
56
57struct _pkinit_cred_info {
58    X509 *cert;
59    EVP_PKEY *key;
60#ifndef WITHOUT_PKCS11
61    CK_BYTE_PTR cert_id;
62    int cert_id_len;
63#endif
64};
65typedef struct _pkinit_cred_info * pkinit_cred_info;
66
67struct _pkinit_identity_crypto_context {
68    pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
69    STACK_OF(X509) *my_certs;   /* available user certs */
70    int cert_index;             /* cert to use out of available certs*/
71    EVP_PKEY *my_key;           /* available user keys if in filesystem */
72    STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
73    STACK_OF(X509) *intermediateCAs;   /* available intermediate ca certs */
74    STACK_OF(X509_CRL) *revoked;    /* available crls */
75    int pkcs11_method;
76    krb5_prompter_fct prompter;
77    void *prompter_data;
78#ifndef WITHOUT_PKCS11
79    char *p11_module_name;
80    CK_SLOT_ID slotid;
81    char *token_label;
82    char *cert_label;
83    char *PIN; /* Solaris Kerberos: */
84    /* These are crypto-specific */
85    void *p11_module;
86    CK_SESSION_HANDLE session;
87    CK_FUNCTION_LIST_PTR p11;
88    CK_BYTE_PTR cert_id;
89    int cert_id_len;
90    CK_MECHANISM_TYPE mech;
91    /* Solaris Kerberos: need to keep some state */
92    uint_t p11flags;
93    /*
94     * Solaris Kerberos:
95     * If PKCS#11 is already being used by the process then C_Finalize should
96     * not be called by pkinit as it would invalidate any PKCS#11 sessions the
97     * process was using prior to loading the pkinit plugin. "finalize_pkcs11"
98     * indicates whether or not C_Finalize should be called by pkinit.
99     */
100    krb5_boolean finalize_pkcs11;
101#endif
102};
103
104/* Solaris Kerberos: need to know if login was done */
105#define	C_LOGIN_DONE 0x1 /* The session is logged in. */
106
107struct _pkinit_plg_crypto_context {
108    DH *dh_1024;
109    DH *dh_2048;
110    DH *dh_4096;
111    ASN1_OBJECT *id_pkinit_authData;
112    ASN1_OBJECT *id_pkinit_authData9;
113    ASN1_OBJECT *id_pkinit_DHKeyData;
114    ASN1_OBJECT *id_pkinit_rkeyData;
115    ASN1_OBJECT *id_pkinit_san;
116    ASN1_OBJECT *id_ms_san_upn;
117    ASN1_OBJECT *id_pkinit_KPClientAuth;
118    ASN1_OBJECT *id_pkinit_KPKdc;
119    ASN1_OBJECT *id_ms_kp_sc_logon;
120    ASN1_OBJECT *id_kp_serverAuth;
121};
122
123struct _pkinit_req_crypto_context {
124    X509 *received_cert;
125    DH *dh;
126};
127
128#define CERT_MAGIC 0x53534c43
129struct _pkinit_cert_data {
130    unsigned int magic;
131    pkinit_plg_crypto_context plgctx;
132    pkinit_req_crypto_context reqctx;
133    pkinit_identity_crypto_context idctx;
134    pkinit_cred_info cred;
135    unsigned int index;	    /* Index of this cred in the creds[] array */
136};
137
138#define ITER_MAGIC 0x53534c49
139struct _pkinit_cert_iter_data {
140    unsigned int magic;
141    pkinit_plg_crypto_context plgctx;
142    pkinit_req_crypto_context reqctx;
143    pkinit_identity_crypto_context idctx;
144    unsigned int index;
145};
146
147/* Solaris Kerberos */
148static krb5_error_code openssl_init(void);
149
150static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
151static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
152
153static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context );
154static void pkinit_fini_dh_params(pkinit_plg_crypto_context );
155
156static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx);
157static void pkinit_fini_certs(pkinit_identity_crypto_context ctx);
158
159static krb5_error_code pkinit_init_pkcs11(pkinit_identity_crypto_context ctx);
160static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx);
161
162static krb5_error_code pkinit_encode_dh_params
163	(BIGNUM *, BIGNUM *, BIGNUM *, unsigned char **, unsigned int *);
164static DH *pkinit_decode_dh_params
165	(DH **, unsigned char **, unsigned int );
166static int pkinit_check_dh_params
167	(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1);
168
169static krb5_error_code pkinit_sign_data
170	(krb5_context context, pkinit_identity_crypto_context cryptoctx,
171		unsigned char *data, unsigned int data_len,
172		unsigned char **sig, unsigned int *sig_len);
173
174static krb5_error_code create_signature
175	(unsigned char **, unsigned int *, unsigned char *, unsigned int,
176		EVP_PKEY *pkey);
177
178static krb5_error_code pkinit_decode_data
179	(krb5_context context, pkinit_identity_crypto_context cryptoctx,
180		unsigned char *data, unsigned int data_len,
181		unsigned char **decoded, unsigned int *decoded_len);
182
183static krb5_error_code decode_data
184	(unsigned char **, unsigned int *, unsigned char *, unsigned int,
185		EVP_PKEY *pkey, X509 *cert);
186
187#ifdef DEBUG_DH
188static void print_dh(DH *, char *);
189static void print_pubkey(BIGNUM *, char *);
190#endif
191
192static int prepare_enc_data
193	(unsigned char *indata, int indata_len, unsigned char **outdata,
194		int *outdata_len);
195
196static int openssl_callback (int, X509_STORE_CTX *);
197static int openssl_callback_ignore_crls (int, X509_STORE_CTX *);
198
199static int pkcs7_decrypt
200	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
201		PKCS7 *p7, BIO *bio);
202
203static BIO * pkcs7_dataDecode
204	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
205		PKCS7 *p7);
206
207static ASN1_OBJECT * pkinit_pkcs7type2oid
208	(pkinit_plg_crypto_context plg_cryptoctx, int pkcs7_type);
209
210static krb5_error_code pkinit_create_sequence_of_principal_identifiers
211	(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx,
212		pkinit_req_crypto_context req_cryptoctx,
213		pkinit_identity_crypto_context id_cryptoctx,
214		int type, krb5_data **out_data);
215
216#ifndef WITHOUT_PKCS11
217static krb5_error_code pkinit_find_private_key
218	(pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage,
219		CK_OBJECT_HANDLE *objp);
220static krb5_error_code pkinit_login
221	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
222		CK_TOKEN_INFO *tip);
223static krb5_error_code pkinit_open_session
224	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx);
225static void * pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p);
226static CK_RV pkinit_C_UnloadModule(void *handle);
227#ifdef SILLYDECRYPT
228CK_RV pkinit_C_Decrypt
229	(pkinit_identity_crypto_context id_cryptoctx,
230		CK_BYTE_PTR pEncryptedData, CK_ULONG  ulEncryptedDataLen,
231		CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);
232#endif
233
234static krb5_error_code pkinit_sign_data_pkcs11
235	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
236		unsigned char *data, unsigned int data_len,
237		unsigned char **sig, unsigned int *sig_len);
238static krb5_error_code pkinit_decode_data_pkcs11
239	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
240		unsigned char *data, unsigned int data_len,
241		unsigned char **decoded_data, unsigned int *decoded_data_len);
242#endif	/* WITHOUT_PKCS11 */
243
244static krb5_error_code pkinit_sign_data_fs
245	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
246		unsigned char *data, unsigned int data_len,
247		unsigned char **sig, unsigned int *sig_len);
248static krb5_error_code pkinit_decode_data_fs
249	(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
250		unsigned char *data, unsigned int data_len,
251		unsigned char **decoded_data, unsigned int *decoded_data_len);
252
253static krb5_error_code der_decode_data
254	(unsigned char *, long, unsigned char **, long *);
255
256static krb5_error_code
257create_krb5_invalidCertificates(krb5_context context,
258				pkinit_plg_crypto_context plg_cryptoctx,
259				pkinit_req_crypto_context req_cryptoctx,
260				pkinit_identity_crypto_context id_cryptoctx,
261				krb5_external_principal_identifier *** ids);
262
263static krb5_error_code
264create_identifiers_from_stack(STACK_OF(X509) *sk,
265			      krb5_external_principal_identifier *** ids);
266#ifdef LONGHORN_BETA_COMPAT
267static int
268wrap_signeddata(unsigned char *data, unsigned int data_len,
269		unsigned char **out, unsigned int *out_len,
270		int is_longhorn_server);
271#else
272static int
273wrap_signeddata(unsigned char *data, unsigned int data_len,
274		unsigned char **out, unsigned int *out_len);
275#endif
276
277/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
278#define ku_reject(x, usage) \
279	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
280
281static char *
282pkinit_pkcs11_code_to_text(int err);
283
284#endif	/* _PKINIT_CRYPTO_OPENSSL_H */
285