1159d09a2SMark Phalan /* 2159d09a2SMark Phalan * COPYRIGHT (C) 2006,2007 3159d09a2SMark Phalan * THE REGENTS OF THE UNIVERSITY OF MICHIGAN 4159d09a2SMark Phalan * ALL RIGHTS RESERVED 5159d09a2SMark Phalan * 6159d09a2SMark Phalan * Permission is granted to use, copy, create derivative works 7159d09a2SMark Phalan * and redistribute this software and such derivative works 8159d09a2SMark Phalan * for any purpose, so long as the name of The University of 9159d09a2SMark Phalan * Michigan is not used in any advertising or publicity 10159d09a2SMark Phalan * pertaining to the use of distribution of this software 11159d09a2SMark Phalan * without specific, written prior authorization. If the 12159d09a2SMark Phalan * above copyright notice or any other identification of the 13159d09a2SMark Phalan * University of Michigan is included in any copy of any 14159d09a2SMark Phalan * portion of this software, then the disclaimer below must 15159d09a2SMark Phalan * also be included. 16159d09a2SMark Phalan * 17159d09a2SMark Phalan * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION 18159d09a2SMark Phalan * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY 19159d09a2SMark Phalan * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF 20159d09a2SMark Phalan * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING 21159d09a2SMark Phalan * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF 22159d09a2SMark Phalan * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 23159d09a2SMark Phalan * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE 24159d09a2SMark Phalan * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR 25159d09a2SMark Phalan * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING 26159d09a2SMark Phalan * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN 27159d09a2SMark Phalan * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF 28159d09a2SMark Phalan * SUCH DAMAGES. 29159d09a2SMark Phalan */ 30159d09a2SMark Phalan 317d2d870eSWill Fiveash /* 3231a29035SMark Phalan * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 33300fdee2SAndy Fiddaman * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. 34*553e44ceSAndrew Stormont * Copyright 2018 RackTop Systems. 357d2d870eSWill Fiveash */ 367d2d870eSWill Fiveash 37159d09a2SMark Phalan #ifndef _PKINIT_CRYPTO_OPENSSL_H 38159d09a2SMark Phalan #define _PKINIT_CRYPTO_OPENSSL_H 39159d09a2SMark Phalan 40159d09a2SMark Phalan #include <openssl/bn.h> 41159d09a2SMark Phalan #include <openssl/dh.h> 42159d09a2SMark Phalan #include <openssl/x509.h> 43159d09a2SMark Phalan #include <openssl/pkcs7.h> 44159d09a2SMark Phalan #include <openssl/pkcs12.h> 45159d09a2SMark Phalan #include <openssl/obj_mac.h> 46159d09a2SMark Phalan #include <openssl/x509v3.h> 47159d09a2SMark Phalan #include <openssl/err.h> 48159d09a2SMark Phalan #include <openssl/evp.h> 49159d09a2SMark Phalan #include <openssl/sha.h> 50159d09a2SMark Phalan #include <openssl/asn1.h> 51159d09a2SMark Phalan #include <openssl/pem.h> 52300fdee2SAndy Fiddaman #include <openssl/rsa.h> 53300fdee2SAndy Fiddaman 54*553e44ceSAndrew Stormont #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 55300fdee2SAndy Fiddaman #include <openssl/asn1_mac.h> 56300fdee2SAndy Fiddaman #else 57300fdee2SAndy Fiddaman #include <openssl/asn1t.h> 58300fdee2SAndy Fiddaman #endif 59159d09a2SMark Phalan 60159d09a2SMark Phalan #include "pkinit.h" 61159d09a2SMark Phalan 62159d09a2SMark Phalan #define DN_BUF_LEN 256 63159d09a2SMark Phalan #define MAX_CREDS_ALLOWED 20 64159d09a2SMark Phalan 65159d09a2SMark Phalan struct _pkinit_cred_info { 66159d09a2SMark Phalan X509 *cert; 67159d09a2SMark Phalan EVP_PKEY *key; 68159d09a2SMark Phalan #ifndef WITHOUT_PKCS11 69159d09a2SMark Phalan CK_BYTE_PTR cert_id; 70159d09a2SMark Phalan int cert_id_len; 71159d09a2SMark Phalan #endif 72159d09a2SMark Phalan }; 73159d09a2SMark Phalan typedef struct _pkinit_cred_info * pkinit_cred_info; 74159d09a2SMark Phalan 75159d09a2SMark Phalan struct _pkinit_identity_crypto_context { 76159d09a2SMark Phalan pkinit_cred_info creds[MAX_CREDS_ALLOWED+1]; 77159d09a2SMark Phalan STACK_OF(X509) *my_certs; /* available user certs */ 78159d09a2SMark Phalan int cert_index; /* cert to use out of available certs*/ 79159d09a2SMark Phalan EVP_PKEY *my_key; /* available user keys if in filesystem */ 80159d09a2SMark Phalan STACK_OF(X509) *trustedCAs; /* available trusted ca certs */ 81159d09a2SMark Phalan STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */ 82159d09a2SMark Phalan STACK_OF(X509_CRL) *revoked; /* available crls */ 83159d09a2SMark Phalan int pkcs11_method; 84159d09a2SMark Phalan krb5_prompter_fct prompter; 85159d09a2SMark Phalan void *prompter_data; 86159d09a2SMark Phalan #ifndef WITHOUT_PKCS11 87159d09a2SMark Phalan char *p11_module_name; 88159d09a2SMark Phalan CK_SLOT_ID slotid; 89159d09a2SMark Phalan char *token_label; 90159d09a2SMark Phalan char *cert_label; 91488060a6SWill Fiveash char *PIN; /* Solaris Kerberos: */ 92159d09a2SMark Phalan /* These are crypto-specific */ 93159d09a2SMark Phalan void *p11_module; 94159d09a2SMark Phalan CK_SESSION_HANDLE session; 95159d09a2SMark Phalan CK_FUNCTION_LIST_PTR p11; 96159d09a2SMark Phalan CK_BYTE_PTR cert_id; 97159d09a2SMark Phalan int cert_id_len; 98159d09a2SMark Phalan CK_MECHANISM_TYPE mech; 997d2d870eSWill Fiveash /* Solaris Kerberos: need to keep some state */ 1007d2d870eSWill Fiveash uint_t p11flags; 101159d09a2SMark Phalan /* 102159d09a2SMark Phalan * Solaris Kerberos: 103159d09a2SMark Phalan * If PKCS#11 is already being used by the process then C_Finalize should 104159d09a2SMark Phalan * not be called by pkinit as it would invalidate any PKCS#11 sessions the 105159d09a2SMark Phalan * process was using prior to loading the pkinit plugin. "finalize_pkcs11" 106159d09a2SMark Phalan * indicates whether or not C_Finalize should be called by pkinit. 107159d09a2SMark Phalan */ 108159d09a2SMark Phalan krb5_boolean finalize_pkcs11; 109159d09a2SMark Phalan #endif 110159d09a2SMark Phalan }; 111159d09a2SMark Phalan 1127d2d870eSWill Fiveash /* Solaris Kerberos: need to know if login was done */ 1137d2d870eSWill Fiveash #define C_LOGIN_DONE 0x1 /* The session is logged in. */ 1149e11d51cSWill Fiveash #define C_PROMPTED_USER 0x2 /* The user was prompted for token. */ 1159e11d51cSWill Fiveash #define C_SKIP_PKCS11_AUTH 0x4 /* User does not want to do PKCS11 auth */ 1167d2d870eSWill Fiveash 117159d09a2SMark Phalan struct _pkinit_plg_crypto_context { 118159d09a2SMark Phalan DH *dh_1024; 119159d09a2SMark Phalan DH *dh_2048; 120159d09a2SMark Phalan DH *dh_4096; 121159d09a2SMark Phalan ASN1_OBJECT *id_pkinit_authData; 122159d09a2SMark Phalan ASN1_OBJECT *id_pkinit_DHKeyData; 123159d09a2SMark Phalan ASN1_OBJECT *id_pkinit_rkeyData; 124159d09a2SMark Phalan ASN1_OBJECT *id_pkinit_san; 125159d09a2SMark Phalan ASN1_OBJECT *id_ms_san_upn; 126159d09a2SMark Phalan ASN1_OBJECT *id_pkinit_KPClientAuth; 127159d09a2SMark Phalan ASN1_OBJECT *id_pkinit_KPKdc; 128159d09a2SMark Phalan ASN1_OBJECT *id_ms_kp_sc_logon; 129159d09a2SMark Phalan ASN1_OBJECT *id_kp_serverAuth; 130159d09a2SMark Phalan }; 131159d09a2SMark Phalan 132159d09a2SMark Phalan struct _pkinit_req_crypto_context { 133159d09a2SMark Phalan X509 *received_cert; 134159d09a2SMark Phalan DH *dh; 135159d09a2SMark Phalan }; 136159d09a2SMark Phalan 137159d09a2SMark Phalan #define CERT_MAGIC 0x53534c43 138159d09a2SMark Phalan struct _pkinit_cert_data { 139159d09a2SMark Phalan unsigned int magic; 140159d09a2SMark Phalan pkinit_plg_crypto_context plgctx; 141159d09a2SMark Phalan pkinit_req_crypto_context reqctx; 142159d09a2SMark Phalan pkinit_identity_crypto_context idctx; 143159d09a2SMark Phalan pkinit_cred_info cred; 144159d09a2SMark Phalan unsigned int index; /* Index of this cred in the creds[] array */ 145159d09a2SMark Phalan }; 146159d09a2SMark Phalan 147159d09a2SMark Phalan #define ITER_MAGIC 0x53534c49 148159d09a2SMark Phalan struct _pkinit_cert_iter_data { 149159d09a2SMark Phalan unsigned int magic; 150159d09a2SMark Phalan pkinit_plg_crypto_context plgctx; 151159d09a2SMark Phalan pkinit_req_crypto_context reqctx; 152159d09a2SMark Phalan pkinit_identity_crypto_context idctx; 153159d09a2SMark Phalan unsigned int index; 154159d09a2SMark Phalan }; 155159d09a2SMark Phalan 15631a29035SMark Phalan /* Solaris Kerberos */ 15731a29035SMark Phalan static krb5_error_code openssl_init(void); 158159d09a2SMark Phalan 159159d09a2SMark Phalan static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ); 160159d09a2SMark Phalan static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ); 161159d09a2SMark Phalan 162159d09a2SMark Phalan static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context ); 163159d09a2SMark Phalan static void pkinit_fini_dh_params(pkinit_plg_crypto_context ); 164159d09a2SMark Phalan 165159d09a2SMark Phalan static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx); 166159d09a2SMark Phalan static void pkinit_fini_certs(pkinit_identity_crypto_context ctx); 167159d09a2SMark Phalan 168159d09a2SMark Phalan static krb5_error_code pkinit_init_pkcs11(pkinit_identity_crypto_context ctx); 169159d09a2SMark Phalan static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx); 170159d09a2SMark Phalan 171159d09a2SMark Phalan static krb5_error_code pkinit_encode_dh_params 172300fdee2SAndy Fiddaman (const BIGNUM *, const BIGNUM *, const BIGNUM *, 173300fdee2SAndy Fiddaman unsigned char **, unsigned int *); 174159d09a2SMark Phalan static DH *pkinit_decode_dh_params 175159d09a2SMark Phalan (DH **, unsigned char **, unsigned int ); 176159d09a2SMark Phalan static int pkinit_check_dh_params 177300fdee2SAndy Fiddaman (const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1, 178300fdee2SAndy Fiddaman const BIGNUM *q1); 179159d09a2SMark Phalan 180159d09a2SMark Phalan static krb5_error_code pkinit_sign_data 181159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context cryptoctx, 182159d09a2SMark Phalan unsigned char *data, unsigned int data_len, 183159d09a2SMark Phalan unsigned char **sig, unsigned int *sig_len); 184159d09a2SMark Phalan 185159d09a2SMark Phalan static krb5_error_code create_signature 186159d09a2SMark Phalan (unsigned char **, unsigned int *, unsigned char *, unsigned int, 187159d09a2SMark Phalan EVP_PKEY *pkey); 188159d09a2SMark Phalan 189159d09a2SMark Phalan static krb5_error_code pkinit_decode_data 190159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context cryptoctx, 191159d09a2SMark Phalan unsigned char *data, unsigned int data_len, 192159d09a2SMark Phalan unsigned char **decoded, unsigned int *decoded_len); 193159d09a2SMark Phalan 194159d09a2SMark Phalan static krb5_error_code decode_data 195159d09a2SMark Phalan (unsigned char **, unsigned int *, unsigned char *, unsigned int, 196159d09a2SMark Phalan EVP_PKEY *pkey, X509 *cert); 197159d09a2SMark Phalan 198159d09a2SMark Phalan #ifdef DEBUG_DH 199159d09a2SMark Phalan static void print_dh(DH *, char *); 200159d09a2SMark Phalan static void print_pubkey(BIGNUM *, char *); 201159d09a2SMark Phalan #endif 202159d09a2SMark Phalan 203159d09a2SMark Phalan static int prepare_enc_data 204159d09a2SMark Phalan (unsigned char *indata, int indata_len, unsigned char **outdata, 205159d09a2SMark Phalan int *outdata_len); 206159d09a2SMark Phalan 207159d09a2SMark Phalan static int openssl_callback (int, X509_STORE_CTX *); 208159d09a2SMark Phalan static int openssl_callback_ignore_crls (int, X509_STORE_CTX *); 209159d09a2SMark Phalan 210159d09a2SMark Phalan static int pkcs7_decrypt 211159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 212159d09a2SMark Phalan PKCS7 *p7, BIO *bio); 213159d09a2SMark Phalan 214159d09a2SMark Phalan static BIO * pkcs7_dataDecode 215159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 216159d09a2SMark Phalan PKCS7 *p7); 217159d09a2SMark Phalan 218159d09a2SMark Phalan static ASN1_OBJECT * pkinit_pkcs7type2oid 219159d09a2SMark Phalan (pkinit_plg_crypto_context plg_cryptoctx, int pkcs7_type); 220159d09a2SMark Phalan 221159d09a2SMark Phalan static krb5_error_code pkinit_create_sequence_of_principal_identifiers 222159d09a2SMark Phalan (krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, 223159d09a2SMark Phalan pkinit_req_crypto_context req_cryptoctx, 224159d09a2SMark Phalan pkinit_identity_crypto_context id_cryptoctx, 225159d09a2SMark Phalan int type, krb5_data **out_data); 226159d09a2SMark Phalan 227159d09a2SMark Phalan #ifndef WITHOUT_PKCS11 228159d09a2SMark Phalan static krb5_error_code pkinit_find_private_key 229159d09a2SMark Phalan (pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage, 230159d09a2SMark Phalan CK_OBJECT_HANDLE *objp); 231159d09a2SMark Phalan static krb5_error_code pkinit_login 232159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 233159d09a2SMark Phalan CK_TOKEN_INFO *tip); 234159d09a2SMark Phalan static void * pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p); 235159d09a2SMark Phalan static CK_RV pkinit_C_UnloadModule(void *handle); 236159d09a2SMark Phalan #ifdef SILLYDECRYPT 237159d09a2SMark Phalan CK_RV pkinit_C_Decrypt 238159d09a2SMark Phalan (pkinit_identity_crypto_context id_cryptoctx, 239159d09a2SMark Phalan CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, 240159d09a2SMark Phalan CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); 241159d09a2SMark Phalan #endif 242159d09a2SMark Phalan 243159d09a2SMark Phalan static krb5_error_code pkinit_sign_data_pkcs11 244159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 245159d09a2SMark Phalan unsigned char *data, unsigned int data_len, 246159d09a2SMark Phalan unsigned char **sig, unsigned int *sig_len); 247159d09a2SMark Phalan static krb5_error_code pkinit_decode_data_pkcs11 248159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 249159d09a2SMark Phalan unsigned char *data, unsigned int data_len, 250159d09a2SMark Phalan unsigned char **decoded_data, unsigned int *decoded_data_len); 251159d09a2SMark Phalan #endif /* WITHOUT_PKCS11 */ 252159d09a2SMark Phalan 253159d09a2SMark Phalan static krb5_error_code pkinit_sign_data_fs 254159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 255159d09a2SMark Phalan unsigned char *data, unsigned int data_len, 256159d09a2SMark Phalan unsigned char **sig, unsigned int *sig_len); 257159d09a2SMark Phalan static krb5_error_code pkinit_decode_data_fs 258159d09a2SMark Phalan (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 259159d09a2SMark Phalan unsigned char *data, unsigned int data_len, 260159d09a2SMark Phalan unsigned char **decoded_data, unsigned int *decoded_data_len); 261159d09a2SMark Phalan 262159d09a2SMark Phalan static krb5_error_code der_decode_data 263159d09a2SMark Phalan (unsigned char *, long, unsigned char **, long *); 264159d09a2SMark Phalan 265159d09a2SMark Phalan static krb5_error_code 266159d09a2SMark Phalan create_krb5_invalidCertificates(krb5_context context, 267159d09a2SMark Phalan pkinit_plg_crypto_context plg_cryptoctx, 268159d09a2SMark Phalan pkinit_req_crypto_context req_cryptoctx, 269159d09a2SMark Phalan pkinit_identity_crypto_context id_cryptoctx, 270159d09a2SMark Phalan krb5_external_principal_identifier *** ids); 271159d09a2SMark Phalan 272159d09a2SMark Phalan static krb5_error_code 273159d09a2SMark Phalan create_identifiers_from_stack(STACK_OF(X509) *sk, 274159d09a2SMark Phalan krb5_external_principal_identifier *** ids); 275159d09a2SMark Phalan #ifdef LONGHORN_BETA_COMPAT 276159d09a2SMark Phalan static int 277159d09a2SMark Phalan wrap_signeddata(unsigned char *data, unsigned int data_len, 278159d09a2SMark Phalan unsigned char **out, unsigned int *out_len, 279159d09a2SMark Phalan int is_longhorn_server); 280159d09a2SMark Phalan #else 281159d09a2SMark Phalan static int 282159d09a2SMark Phalan wrap_signeddata(unsigned char *data, unsigned int data_len, 283159d09a2SMark Phalan unsigned char **out, unsigned int *out_len); 284159d09a2SMark Phalan #endif 285159d09a2SMark Phalan 286159d09a2SMark Phalan /* This handy macro borrowed from crypto/x509v3/v3_purp.c */ 287300fdee2SAndy Fiddaman 288*553e44ceSAndrew Stormont #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 289159d09a2SMark Phalan #define ku_reject(x, usage) \ 290159d09a2SMark Phalan (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) 291300fdee2SAndy Fiddaman #else 292300fdee2SAndy Fiddaman #define ku_reject(x, usage) \ 293300fdee2SAndy Fiddaman ((X509_get_extension_flags(x) & EXFLAG_KUSAGE) && \ 294300fdee2SAndy Fiddaman !(X509_get_key_usage(x) & (usage))) 295300fdee2SAndy Fiddaman #endif 296159d09a2SMark Phalan 297159d09a2SMark Phalan static char * 298159d09a2SMark Phalan pkinit_pkcs11_code_to_text(int err); 299159d09a2SMark Phalan 300159d09a2SMark Phalan #endif /* _PKINIT_CRYPTO_OPENSSL_H */ 301