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