Path: blob/main/crypto/krb5/src/plugins/preauth/pkinit/pkinit_crypto.h
34923 views
/*1* COPYRIGHT (C) 20072* THE REGENTS OF THE UNIVERSITY OF MICHIGAN3* ALL RIGHTS RESERVED4*5* Permission is granted to use, copy, create derivative works6* and redistribute this software and such derivative works7* for any purpose, so long as the name of The University of8* Michigan is not used in any advertising or publicity9* pertaining to the use of distribution of this software10* without specific, written prior authorization. If the11* above copyright notice or any other identification of the12* University of Michigan is included in any copy of any13* portion of this software, then the disclaimer below must14* also be included.15*16* THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION17* FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY18* PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF19* MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING20* WITHOUT LIMITATION THE IMPLIED WARRANTIES OF21* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE22* REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE23* FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR24* CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING25* OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN26* IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGES.28*/2930/*31* This header defines the cryptographic interface32*/3334#ifndef _PKINIT_CRYPTO_H35#define _PKINIT_CRYPTO_H3637#include <krb5/krb5.h>38#include <krb5/preauth_plugin.h>39#include <k5-int-pkinit.h>40#include <profile.h>41#include "pkinit_accessor.h"4243/*44* these describe the CMS message types45*/46enum cms_msg_types {47CMS_SIGN_CLIENT,48CMS_SIGN_SERVER,49CMS_ENVEL_SERVER50};5152/*53* storage types for identity information54*/55#define IDTYPE_FILE 156#define IDTYPE_DIR 257#define IDTYPE_PKCS11 358#define IDTYPE_ENVVAR 459#define IDTYPE_PKCS12 56061/*62* ca/crl types63*/64#define CATYPE_ANCHORS 165#define CATYPE_INTERMEDIATES 266#define CATYPE_CRLS 36768/*69* The following represent Key Usage values that we70* may care about in a certificate71*/72#define PKINIT_KU_DIGITALSIGNATURE 0x8000000073#define PKINIT_KU_KEYENCIPHERMENT 0x400000007475/*76* The following represent Extended Key Usage oid values77* that we may care about in a certificate78*/79#define PKINIT_EKU_PKINIT 0x8000000080#define PKINIT_EKU_MSSCLOGIN 0x4000000081#define PKINIT_EKU_CLIENTAUTH 0x2000000082#define PKINIT_EKU_EMAILPROTECTION 0x10000000838485/* Handle to cert, opaque above crypto interface */86typedef struct _pkinit_cert_info *pkinit_cert_handle;8788/* Handle to cert iteration information, opaque above crypto interface */89typedef struct _pkinit_cert_iter_info *pkinit_cert_iter_handle;9091#define PKINIT_ITER_NO_MORE 0x11111111 /* XXX */9293typedef struct _pkinit_cert_matching_data {94char *subject_dn; /* rfc2253-style subject name string */95char *issuer_dn; /* rfc2253-style issuer name string */96unsigned int ku_bits; /* key usage information */97unsigned int eku_bits; /* extended key usage information */98krb5_principal *sans; /* Null-terminated array of PKINIT SANs */99char **upns; /* Null-terimnated array of UPN SANs */100} pkinit_cert_matching_data;101102/*103* Functions to initialize and cleanup crypto contexts104*/105krb5_error_code pkinit_init_plg_crypto(krb5_context,106pkinit_plg_crypto_context *);107void pkinit_fini_plg_crypto(pkinit_plg_crypto_context);108109krb5_error_code pkinit_init_req_crypto(pkinit_req_crypto_context *);110void pkinit_fini_req_crypto(pkinit_req_crypto_context);111112krb5_error_code pkinit_init_identity_crypto(pkinit_identity_crypto_context *);113void pkinit_fini_identity_crypto(pkinit_identity_crypto_context);114/**Create a pkinit ContentInfo*/115krb5_error_code cms_contentinfo_create116(krb5_context context, /* IN */117pkinit_plg_crypto_context plg_cryptoctx, /* IN */118pkinit_req_crypto_context req_cryptoctx, /* IN */119pkinit_identity_crypto_context id_cryptoctx, /* IN */120int cms_msg_type,121unsigned char *in_data, unsigned int in_length,122unsigned char **out_data, unsigned int *out_data_len);123124/*125* this function creates a CMS message where eContentType is SignedData126*/127krb5_error_code cms_signeddata_create128(krb5_context context, /* IN */129pkinit_plg_crypto_context plg_cryptoctx, /* IN */130pkinit_req_crypto_context req_cryptoctx, /* IN */131pkinit_identity_crypto_context id_cryptoctx, /* IN */132int cms_msg_type, /* IN133specifies CMS_SIGN_CLIENT for client-side CMS message134and CMS_SIGN_SERVER for kdc-side */135unsigned char *auth_pack, /* IN136contains DER encoded AuthPack (CMS_SIGN_CLIENT)137or DER encoded DHRepInfo (CMS_SIGN_SERVER) */138unsigned int auth_pack_len, /* IN139contains length of auth_pack */140unsigned char **signed_data, /* OUT141for CMS_SIGN_CLIENT receives DER encoded142SignedAuthPack (CMS_SIGN_CLIENT) or DER143encoded DHInfo (CMS_SIGN_SERVER) */144unsigned int *signed_data_len); /* OUT145receives length of signed_data */146147/*148* this function verifies a CMS message where eContentType is SignedData149*/150krb5_error_code cms_signeddata_verify151(krb5_context context, /* IN */152pkinit_plg_crypto_context plg_cryptoctx, /* IN */153pkinit_req_crypto_context req_cryptoctx, /* IN */154pkinit_identity_crypto_context id_cryptoctx, /* IN */155int cms_msg_type, /* IN156specifies CMS_SIGN_CLIENT for client-side157CMS message and CMS_SIGN_SERVER for kdc-side */158int require_crl_checking, /* IN159specifies whether CRL checking should be160strictly enforced, i.e. if no CRLs available161for the CA then fail verification.162note, if the value is 0, crls are still163checked if present */164unsigned char *signed_data, /* IN165contains DER encoded SignedAuthPack (CMS_SIGN_CLIENT)166or DER encoded DHInfo (CMS_SIGN_SERVER) */167unsigned int signed_data_len, /* IN168contains length of signed_data*/169unsigned char **auth_pack, /* OUT170receives DER encoded AuthPack (CMS_SIGN_CLIENT)171or DER encoded DHRepInfo (CMS_SIGN_SERVER)*/172unsigned int *auth_pack_len, /* OUT173receives length of auth_pack */174unsigned char **authz_data, /* OUT175receives required authorization data that176contains the verified certificate chain177(only used by the KDC) */178unsigned int *authz_data_len, /* OUT179receives length of authz_data */180int *is_signed); /* OUT181receives whether message is signed */182183/*184* This function retrieves the signer's identity, in a form that could185* be passed back in to a future invocation of this module as a candidate186* client identity location.187*/188krb5_error_code crypto_retrieve_signer_identity189(krb5_context context, /* IN */190pkinit_identity_crypto_context id_cryptoctx, /* IN */191const char **identity); /* OUT */192193/*194* this function returns SAN information found in the195* received certificate. at least one of pkinit_sans,196* upn_sans, or kdc_hostnames must be non-NULL.197*/198krb5_error_code crypto_retrieve_cert_sans199(krb5_context context, /* IN */200pkinit_plg_crypto_context plg_cryptoctx, /* IN */201pkinit_req_crypto_context req_cryptoctx, /* IN */202pkinit_identity_crypto_context id_cryptoctx, /* IN */203krb5_principal **pkinit_sans, /* OUT204if non-NULL, a null-terminated array of205id-pkinit-san values found in the certificate206are returned */207char ***upn_sans, /* OUT208if non-NULL, a null-terminated array of209id-ms-upn-san values found in the certificate210are returned */211unsigned char ***kdc_hostname); /* OUT212if non-NULL, a null-terminated array of213dNSName (hostname) SAN values found in the214certificate are returned */215216/*217* this function checks for acceptable key usage values218* in the received certificate.219*220* when checking a received kdc certificate, it looks for221* the kpKdc key usage. if allow_secondary_usage is222* non-zero, it will also accept kpServerAuth.223*224* when checking a received user certificate, it looks for225* kpClientAuth key usage. if allow_secondary_usage is226* non-zero, it will also accept id-ms-sc-logon EKU.227*228* this function must also assert that the digitalSignature229* key usage is consistent.230*/231krb5_error_code crypto_check_cert_eku232(krb5_context context, /* IN */233pkinit_plg_crypto_context plg_cryptoctx, /* IN */234pkinit_req_crypto_context req_cryptoctx, /* IN */235pkinit_identity_crypto_context id_cryptoctx, /* IN */236int checking_kdc_cert, /* IN237specifies if the received certificate is238a KDC certificate (non-zero),239or a user certificate (zero) */240int allow_secondary_usage, /* IN241specifies if the secondary key usage242should be accepted or not (see above) */243int *eku_valid); /* OUT244receives non-zero if an acceptable EKU was found */245246/*247* this function implements clients first part of the DH protocol.248* client selects its DH parameters and pub key249*/250krb5_error_code client_create_dh251(krb5_context context, /* IN */252pkinit_plg_crypto_context plg_cryptoctx, /* IN */253pkinit_req_crypto_context req_cryptoctx, /* IN */254pkinit_identity_crypto_context id_cryptoctx, /* IN */255int dh_size, /* IN256specifies the DH modulous, eg 1024, 2048, or 4096 */257krb5_data *spki_out); /* OUT258receives SubjectPublicKeyInfo encoding */259260/*261* this function completes client's the DH protocol. client262* processes received DH pub key from the KDC and computes263* the DH secret key264*/265krb5_error_code client_process_dh266(krb5_context context, /* IN */267pkinit_plg_crypto_context plg_cryptoctx, /* IN */268pkinit_req_crypto_context req_cryptoctx, /* IN */269pkinit_identity_crypto_context id_cryptoctx, /* IN */270unsigned char *dh_pubkey, /* IN271contains client's DER encoded DH pub key */272unsigned int dh_pubkey_len, /* IN273contains length of dh_pubkey */274unsigned char **client_key_out, /* OUT275receives DH secret key */276unsigned int *client_key_len_out); /* OUT277receives length of DH secret key */278279/*280* this function implements the KDC first part of the DH protocol.281* it decodes the client's DH parameters and pub key and checks282* if they are acceptable.283*/284krb5_error_code server_check_dh285(krb5_context context, /* IN */286pkinit_plg_crypto_context plg_cryptoctx, /* IN */287pkinit_req_crypto_context req_cryptoctx, /* IN */288pkinit_identity_crypto_context id_cryptoctx, /* IN */289const krb5_data *client_spki, /* IN290SubjectPublicKeyInfo encoding from client */291int minbits); /* IN292the minimum number of key bits acceptable */293294/*295* this function completes the KDC's DH protocol. The KDC generates296* its DH pub key and computes the DH secret key297*/298krb5_error_code server_process_dh299(krb5_context context, /* IN */300pkinit_plg_crypto_context plg_cryptoctx, /* IN */301pkinit_req_crypto_context req_cryptoctx, /* IN */302pkinit_identity_crypto_context id_cryptoctx, /* IN */303unsigned char **dh_pubkey_out, /* OUT304receives KDC's DER encoded DH pub key */305unsigned int *dh_pubkey_len_out, /* OUT306receives length of dh_pubkey */307unsigned char **server_key_out, /* OUT308receives DH secret key */309unsigned int *server_key_len_out); /* OUT310receives length of DH secret key */311312/*313* this functions takes in crypto specific representation of314* supportedCMSTypes and creates a list of315* krb5_algorithm_identifier316*/317krb5_error_code create_krb5_supportedCMSTypes318(krb5_context context, /* IN */319pkinit_plg_crypto_context plg_cryptoctx, /* IN */320pkinit_req_crypto_context req_cryptoctx, /* IN */321pkinit_identity_crypto_context id_cryptoctx, /* IN */322krb5_algorithm_identifier ***supportedCMSTypes); /* OUT */323324/*325* this functions takes in crypto specific representation of326* trustedCertifiers and creates a list of327* krb5_external_principal_identifier328*/329krb5_error_code create_krb5_trustedCertifiers330(krb5_context context, /* IN */331pkinit_plg_crypto_context plg_cryptoctx, /* IN */332pkinit_req_crypto_context req_cryptoctx, /* IN */333pkinit_identity_crypto_context id_cryptoctx, /* IN */334krb5_external_principal_identifier ***trustedCertifiers); /* OUT */335336/*337* this functions takes in crypto specific representation of the338* KDC's certificate and creates a DER encoded kdcPKId339*/340krb5_error_code create_issuerAndSerial341(krb5_context context, /* IN */342pkinit_plg_crypto_context plg_cryptoctx, /* IN */343pkinit_req_crypto_context req_cryptoctx, /* IN */344pkinit_identity_crypto_context id_cryptoctx, /* IN */345unsigned char **kdcId_buf, /* OUT346receives DER encoded kdcPKId */347unsigned int *kdcId_len); /* OUT348receives length of encoded kdcPKId */349350/*351* These functions manipulate the deferred-identities list in the identity352* context, which is opaque outside of the crypto-specific bits.353*/354const pkinit_deferred_id * crypto_get_deferred_ids355(krb5_context context, pkinit_identity_crypto_context id_cryptoctx);356krb5_error_code crypto_set_deferred_id357(krb5_context context,358pkinit_identity_crypto_context id_cryptoctx,359const char *identity, const char *password);360361/*362* process the values from idopts and obtain the cert(s)363* specified by those options, populating the id_cryptoctx.364*/365krb5_error_code crypto_load_certs366(krb5_context context, /* IN */367pkinit_plg_crypto_context plg_cryptoctx, /* IN */368pkinit_req_crypto_context req_cryptoctx, /* IN */369pkinit_identity_opts *idopts, /* IN */370pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */371krb5_principal princ, /* IN */372krb5_boolean defer_id_prompts); /* IN */373374/*375* Free up information held from crypto_load_certs()376*/377krb5_error_code crypto_free_cert_info378(krb5_context context,379pkinit_plg_crypto_context plg_cryptoctx,380pkinit_req_crypto_context req_cryptoctx,381pkinit_identity_crypto_context id_cryptoctx);382383384/*385* Get a null-terminated list of certificate matching data objects for the386* certificates loaded in id_cryptoctx.387*/388krb5_error_code389crypto_cert_get_matching_data(krb5_context context,390pkinit_plg_crypto_context plg_cryptoctx,391pkinit_req_crypto_context req_cryptoctx,392pkinit_identity_crypto_context id_cryptoctx,393pkinit_cert_matching_data ***md_out);394395/*396* Free a matching data object.397*/398void399crypto_cert_free_matching_data(krb5_context context,400pkinit_cert_matching_data *md);401402/*403* Free a list of matching data objects.404*/405void406crypto_cert_free_matching_data_list(krb5_context context,407pkinit_cert_matching_data **matchdata);408409/*410* Choose one of the certificates loaded in idctx to use for PKINIT client411* operations. cred_index must be an index into the array of matching objects412* returned by crypto_cert_get_matching_data().413*/414krb5_error_code415crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,416size_t cred_index);417418/*419* Select the default certificate as "the chosen one"420*/421krb5_error_code crypto_cert_select_default422(krb5_context context, /* IN */423pkinit_plg_crypto_context plg_cryptoctx, /* IN */424pkinit_req_crypto_context req_cryptoctx, /* IN */425pkinit_identity_crypto_context id_cryptoctx); /* IN */426427/*428* process the values from idopts and obtain the anchor or429* intermediate certificates, or crls specified by idtype,430* catype, and id431*/432krb5_error_code crypto_load_cas_and_crls433(krb5_context context, /* IN */434pkinit_plg_crypto_context plg_cryptoctx, /* IN */435pkinit_req_crypto_context req_cryptoctx, /* IN */436pkinit_identity_opts *idopts, /* IN */437pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */438int idtype, /* IN439defines the storage type (file, directory, etc) */440int catype, /* IN441defines the ca type (anchor, intermediate, crls) */442char *id); /* IN443defines the location (filename, directory name, etc) */444445/*446* on the client, obtain the kdc's certificate to include447* in a request448*/449krb5_error_code pkinit_get_kdc_cert450(krb5_context context, /* IN */451pkinit_plg_crypto_context plg_cryptoctx, /* IN */452pkinit_req_crypto_context req_cryptoctx, /* IN */453pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */454krb5_principal princ); /* IN */455456/*457* this function creates edata that contains TD-DH-PARAMETERS458*/459krb5_error_code pkinit_create_td_dh_parameters460(krb5_context context, /* IN */461pkinit_plg_crypto_context plg_cryptoctx, /* IN */462pkinit_req_crypto_context req_cryptoctx, /* IN */463pkinit_identity_crypto_context id_cryptoctx, /* IN */464pkinit_plg_opts *opts, /* IN */465krb5_pa_data ***e_data_out); /* OUT */466467/*468* this function processes edata that contains TD-DH-PARAMETERS.469* the client processes the received acceptable by KDC DH470* parameters and picks the first acceptable to it. it matches471* them against the known DH parameters.472*/473krb5_error_code pkinit_process_td_dh_params474(krb5_context context, /* IN */475pkinit_plg_crypto_context plg_cryptoctx, /* IN */476pkinit_req_crypto_context req_cryptoctx, /* IN */477pkinit_identity_crypto_context id_cryptoctx, /* IN */478krb5_algorithm_identifier **algId, /* IN */479int *new_dh_size); /* OUT480receives the new DH modulus to use in the new AS-REQ */481482/*483* this function creates edata that contains TD-INVALID-CERTIFICATES484*/485krb5_error_code pkinit_create_td_invalid_certificate486(krb5_context context, /* IN */487pkinit_plg_crypto_context plg_cryptoctx, /* IN */488pkinit_req_crypto_context req_cryptoctx, /* IN */489pkinit_identity_crypto_context id_cryptoctx, /* IN */490krb5_pa_data ***e_data_out); /* OUT */491492/*493* this function creates edata that contains TD-TRUSTED-CERTIFIERS494*/495krb5_error_code pkinit_create_td_trusted_certifiers496(krb5_context context, /* IN */497pkinit_plg_crypto_context plg_cryptoctx, /* IN */498pkinit_req_crypto_context req_cryptoctx, /* IN */499pkinit_identity_crypto_context id_cryptoctx, /* IN */500krb5_pa_data ***e_data_out); /* OUT */501502/*503* this function processes edata that contains either504* TD-TRUSTED-CERTIFICATES or TD-INVALID-CERTIFICATES.505* current implementation only decodes the received message506* but does not act on it507*/508krb5_error_code pkinit_process_td_trusted_certifiers509(krb5_context context, /* IN */510pkinit_plg_crypto_context plg_cryptoctx, /* IN */511pkinit_req_crypto_context req_cryptoctx, /* IN */512pkinit_identity_crypto_context id_cryptoctx, /* IN */513krb5_external_principal_identifier **trustedCertifiers, /* IN */514int td_type); /* IN */515516/*517* this function checks if the received kdcPKId matches518* the KDC's certificate519*/520krb5_error_code pkinit_check_kdc_pkid521(krb5_context context, /* IN */522pkinit_plg_crypto_context plg_cryptoctx, /* IN */523pkinit_req_crypto_context req_cryptoctx, /* IN */524pkinit_identity_crypto_context id_cryptoctx, /* IN */525unsigned char *pdid_buf, /* IN526contains DER encoded kdcPKId */527unsigned int pkid_len, /* IN528contains length of pdid_buf */529int *valid_kdcPkId); /* OUT5301 if kdcPKId matches, otherwise 0 */531532krb5_error_code pkinit_identity_set_prompter533(pkinit_identity_crypto_context id_cryptoctx, /* IN */534krb5_prompter_fct prompter, /* IN */535void *prompter_data); /* IN */536537krb5_error_code538pkinit_kdf(krb5_context context, krb5_data *secret, const krb5_data *alg_oid,539krb5_const_principal party_u_info,540krb5_const_principal party_v_info, krb5_enctype enctype,541const krb5_data *as_req, const krb5_data *pk_as_rep,542krb5_keyblock *key_block);543544extern const krb5_data kdf_sha1_id;545extern const krb5_data kdf_sha256_id;546extern const krb5_data kdf_sha512_id;547extern const krb5_data cms_sha1_id;548extern const krb5_data cms_sha256_id;549extern const krb5_data cms_sha384_id;550extern const krb5_data cms_sha512_id;551extern const krb5_data oakley_1024;552extern const krb5_data oakley_2048;553extern const krb5_data oakley_4096;554extern const krb5_data ec_p256;555extern const krb5_data ec_p384;556extern const krb5_data ec_p521;557extern const krb5_data dh_oid;558extern const krb5_data ec_oid;559560/**561* An ordered set of OIDs, stored as krb5_data, of KDF algorithms562* supported by this implementation. The order of this array controls563* the order in which the server will pick.564*/565extern krb5_data const * const supported_kdf_alg_ids[];566567/* CMS signature algorithms supported by this implementation, in order of568* decreasing preference. */569extern krb5_data const * const supported_cms_algs[];570571krb5_error_code572crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,573uint8_t **der_out, size_t *der_len);574575krb5_error_code576crypto_req_cert_matching_data(krb5_context context,577pkinit_plg_crypto_context plgctx,578pkinit_req_crypto_context reqctx,579pkinit_cert_matching_data **md_out);580581int parse_dh_min_bits(krb5_context context, const char *str);582583/* Generate a SHA-1 checksum over body in *cksum1_out and a SHA-256 checksum584* over body in *cksum2_out with appropriate metadata. */585krb5_error_code586crypto_generate_checksums(krb5_context context, const krb5_data *body,587krb5_data *cksum1_out,588krb5_pachecksum2 **cksum2_out);589590/* Verify the SHA-1 checksum in cksum1 and the tagged checksum in cksum2.591* cksum2 may be NULL, in which case only cksum1 is verified. */592krb5_error_code593crypto_verify_checksums(krb5_context context, krb5_data *body,594const krb5_data *cksum1,595const krb5_pachecksum2 *cksum2);596597#endif /* _PKINIT_CRYPTO_H */598599600