1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * COPYRIGHT (C) 2006,2007 4 * THE REGENTS OF THE UNIVERSITY OF MICHIGAN 5 * ALL RIGHTS RESERVED 6 * 7 * Permission is granted to use, copy, create derivative works 8 * and redistribute this software and such derivative works 9 * for any purpose, so long as the name of The University of 10 * Michigan is not used in any advertising or publicity 11 * pertaining to the use of distribution of this software 12 * without specific, written prior authorization. If the 13 * above copyright notice or any other identification of the 14 * University of Michigan is included in any copy of any 15 * portion of this software, then the disclaimer below must 16 * also be included. 17 * 18 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION 19 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY 20 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF 21 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING 22 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 24 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE 25 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR 26 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING 27 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN 28 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGES. 30 */ 31 32 #include "k5-int.h" 33 #include "k5-buf.h" 34 #include "k5-err.h" 35 #include "k5-hex.h" 36 #include "pkinit.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/sha.h> 48 #include <openssl/asn1.h> 49 #include <openssl/pem.h> 50 #include <openssl/asn1t.h> 51 #include <openssl/cms.h> 52 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 53 #include <openssl/core_names.h> 54 #include <openssl/kdf.h> 55 #include <openssl/decoder.h> 56 #include <openssl/params.h> 57 #endif 58 59 #define DN_BUF_LEN 256 60 #define MAX_CREDS_ALLOWED 20 61 62 struct _pkinit_cred_info { 63 char *name; 64 X509 *cert; 65 EVP_PKEY *key; 66 #ifndef WITHOUT_PKCS11 67 CK_BYTE_PTR cert_id; 68 int cert_id_len; 69 #endif 70 }; 71 typedef struct _pkinit_cred_info *pkinit_cred_info; 72 73 struct _pkinit_identity_crypto_context { 74 pkinit_cred_info creds[MAX_CREDS_ALLOWED+1]; 75 X509 *my_cert; /* selected user or KDC cert */ 76 char *identity; /* identity name for user cert */ 77 EVP_PKEY *my_key; /* selected cert key if in filesystem */ 78 STACK_OF(X509) *trustedCAs; /* available trusted ca certs */ 79 STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */ 80 STACK_OF(X509_CRL) *revoked; /* available crls */ 81 int pkcs11_method; 82 krb5_prompter_fct prompter; 83 void *prompter_data; 84 #ifndef WITHOUT_PKCS11 85 char *p11_module_name; 86 CK_SLOT_ID slotid; 87 char *token_label; 88 char *cert_label; 89 /* These are crypto-specific. */ 90 struct plugin_file_handle *p11_module; 91 CK_SESSION_HANDLE session; 92 CK_FUNCTION_LIST_PTR p11; 93 uint8_t *cert_id; 94 size_t cert_id_len; 95 #endif 96 krb5_boolean defer_id_prompt; 97 pkinit_deferred_id *deferred_ids; 98 }; 99 100 struct _pkinit_plg_crypto_context { 101 EVP_PKEY *dh_1024; 102 EVP_PKEY *dh_2048; 103 EVP_PKEY *dh_4096; 104 EVP_PKEY *ec_p256; 105 EVP_PKEY *ec_p384; 106 EVP_PKEY *ec_p521; 107 ASN1_OBJECT *id_pkinit_authData; 108 ASN1_OBJECT *id_pkinit_DHKeyData; 109 ASN1_OBJECT *id_pkinit_rkeyData; 110 ASN1_OBJECT *id_pkinit_san; 111 ASN1_OBJECT *id_ms_san_upn; 112 ASN1_OBJECT *id_pkinit_KPClientAuth; 113 ASN1_OBJECT *id_pkinit_KPKdc; 114 ASN1_OBJECT *id_ms_kp_sc_logon; 115 ASN1_OBJECT *id_kp_serverAuth; 116 }; 117 118 struct _pkinit_req_crypto_context { 119 X509 *received_cert; 120 EVP_PKEY *client_pkey; 121 }; 122 123 static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ); 124 static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ); 125 126 static krb5_error_code pkinit_init_dh_params(krb5_context, 127 pkinit_plg_crypto_context); 128 static void pkinit_fini_dh_params(pkinit_plg_crypto_context ); 129 130 static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx); 131 static void pkinit_fini_certs(pkinit_identity_crypto_context ctx); 132 133 static krb5_error_code pkinit_init_pkcs11(pkinit_identity_crypto_context ctx); 134 static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx); 135 136 static krb5_error_code pkinit_sign_data 137 (krb5_context context, pkinit_identity_crypto_context cryptoctx, 138 unsigned char *data, unsigned int data_len, 139 unsigned char **sig, unsigned int *sig_len); 140 141 static krb5_error_code create_signature 142 (unsigned char **, unsigned int *, unsigned char *, unsigned int, 143 EVP_PKEY *pkey); 144 145 #ifdef DEBUG_DH 146 static void print_dh(DH *, char *); 147 static void print_pubkey(BIGNUM *, char *); 148 #endif 149 150 static int openssl_callback (int, X509_STORE_CTX *); 151 static int openssl_callback_ignore_crls (int, X509_STORE_CTX *); 152 153 static ASN1_OBJECT * pkinit_pkcs7type2oid 154 (pkinit_plg_crypto_context plg_cryptoctx, int pkcs7_type); 155 156 static krb5_error_code pkinit_create_sequence_of_principal_identifiers 157 (krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, 158 pkinit_req_crypto_context req_cryptoctx, 159 pkinit_identity_crypto_context id_cryptoctx, 160 int type, krb5_pa_data ***e_data_out); 161 162 #ifndef WITHOUT_PKCS11 163 static krb5_error_code 164 pkinit_find_private_key(krb5_context context, 165 pkinit_identity_crypto_context id_cryptoctx, 166 CK_ATTRIBUTE_TYPE usage, 167 CK_OBJECT_HANDLE *objp); 168 static krb5_error_code pkinit_login 169 (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 170 CK_TOKEN_INFO *tip, const char *password); 171 static krb5_error_code pkinit_open_session 172 (krb5_context context, pkinit_identity_crypto_context id_cryptoctx); 173 #ifdef SILLYDECRYPT 174 CK_RV pkinit_C_Decrypt 175 (pkinit_identity_crypto_context id_cryptoctx, 176 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, 177 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); 178 #endif 179 180 static krb5_error_code pkinit_sign_data_pkcs11 181 (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 182 unsigned char *data, unsigned int data_len, 183 unsigned char **sig, unsigned int *sig_len); 184 185 static krb5_error_code p11err(krb5_context context, CK_RV rv, const char *op); 186 #endif /* WITHOUT_PKCS11 */ 187 188 static krb5_error_code pkinit_sign_data_fs 189 (krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 190 unsigned char *data, unsigned int data_len, 191 unsigned char **sig, unsigned int *sig_len); 192 193 static krb5_error_code 194 create_krb5_invalidCertificates(krb5_context context, 195 pkinit_plg_crypto_context plg_cryptoctx, 196 pkinit_req_crypto_context req_cryptoctx, 197 pkinit_identity_crypto_context id_cryptoctx, 198 krb5_external_principal_identifier *** ids); 199 200 static krb5_error_code 201 create_identifiers_from_stack(STACK_OF(X509) *sk, 202 krb5_external_principal_identifier *** ids); 203 204 #if OPENSSL_VERSION_NUMBER < 0x10100000L 205 206 /* 1.1 standardizes constructor and destructor names, renaming 207 * EVP_MD_CTX_{create,destroy} and deprecating ASN1_STRING_data. */ 208 209 #define EVP_MD_CTX_new EVP_MD_CTX_create 210 #define EVP_MD_CTX_free EVP_MD_CTX_destroy 211 #define ASN1_STRING_get0_data ASN1_STRING_data 212 213 /* 214 * 1.1 adds DHX support, which uses the RFC 3279 DomainParameters encoding we 215 * need for PKINIT. For 1.0 we must use the original DH type when creating 216 * EVP_PKEY objects. 217 */ 218 #define EVP_PKEY_DHX EVP_PKEY_DH 219 220 /* 1.1 makes many handle types opaque and adds accessors. Add compatibility 221 * versions of the new accessors we use for pre-1.1. */ 222 223 #define OBJ_get0_data(o) ((o)->data) 224 #define OBJ_length(o) ((o)->length) 225 226 #define DH_set0_key compat_dh_set0_key 227 static int 228 compat_dh_set0_key(DH *dh, BIGNUM *pub, BIGNUM *priv) 229 { 230 if (pub != NULL) { 231 BN_clear_free(dh->pub_key); 232 dh->pub_key = pub; 233 } 234 if (priv != NULL) { 235 BN_clear_free(dh->priv_key); 236 dh->priv_key = priv; 237 } 238 return 1; 239 } 240 241 #define DH_get0_key compat_dh_get0_key 242 static void compat_dh_get0_key(const DH *dh, const BIGNUM **pub, 243 const BIGNUM **priv) 244 { 245 if (pub != NULL) 246 *pub = dh->pub_key; 247 if (priv != NULL) 248 *priv = dh->priv_key; 249 } 250 251 #define EVP_PKEY_get0_DH compat_get0_DH 252 static DH * 253 compat_get0_DH(const EVP_PKEY *pkey) 254 { 255 if (pkey->type != EVP_PKEY_DH) 256 return NULL; 257 return pkey->pkey.dh; 258 259 } 260 261 #define EVP_PKEY_get0_EC_KEY compat_get0_EC 262 static EC_KEY * 263 compat_get0_EC(const EVP_PKEY *pkey) 264 { 265 if (pkey->type != EVP_PKEY_EC) 266 return NULL; 267 return pkey->pkey.ec; 268 } 269 270 #define ECDSA_SIG_set0 compat_ECDSA_SIG_set0 271 static int 272 compat_ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) 273 { 274 sig->r = r; 275 sig->s = s; 276 return 1; 277 } 278 279 /* Return true if the cert c includes a key usage which doesn't include u. 280 * Define using direct member access for pre-1.1. */ 281 #define ku_reject(c, u) \ 282 (((c)->ex_flags & EXFLAG_KUSAGE) && !((c)->ex_kusage & (u))) 283 284 #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ 285 286 /* Return true if the cert x includes a key usage which doesn't include u. */ 287 #define ku_reject(c, u) (!(X509_get_key_usage(c) & (u))) 288 289 #endif 290 291 #if OPENSSL_VERSION_NUMBER < 0x30000000L 292 /* OpenSSL 3.0 changes several preferred function names. */ 293 #define EVP_PKEY_parameters_eq EVP_PKEY_cmp_parameters 294 #define EVP_PKEY_get_size EVP_PKEY_size 295 #define EVP_PKEY_get_bits EVP_PKEY_bits 296 #define EVP_PKEY_get_base_id EVP_PKEY_base_id 297 298 /* 299 * Convert *dh to an EVP_PKEY object, taking ownership of *dh and setting it to 300 * NULL. On error, return NULL and do not take ownership of or change *dh. 301 * OpenSSL 3.0 deprecates the low-level DH interfaces, so this helper will only 302 * be used with prior versions. 303 */ 304 static EVP_PKEY * 305 dh_to_pkey(DH **dh) 306 { 307 EVP_PKEY *pkey; 308 309 pkey = EVP_PKEY_new(); 310 if (pkey == NULL) 311 return NULL; 312 if (!EVP_PKEY_assign(pkey, EVP_PKEY_DHX, *dh)) { 313 EVP_PKEY_free(pkey); 314 return NULL; 315 } 316 *dh = NULL; 317 return pkey; 318 } 319 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 320 321 /* Encode a bignum as an ASN.1 integer in DER. */ 322 static int 323 encode_bn_der(const BIGNUM *bn, uint8_t **der_out, int *len_out) 324 { 325 ASN1_INTEGER *intval; 326 int len; 327 uint8_t *der = NULL, *outptr; 328 329 intval = BN_to_ASN1_INTEGER(bn, NULL); 330 if (intval == NULL) 331 return 0; 332 len = i2d_ASN1_INTEGER(intval, NULL); 333 if (len > 0 && (outptr = der = malloc(len)) != NULL) 334 (void)i2d_ASN1_INTEGER(intval, &outptr); 335 ASN1_INTEGER_free(intval); 336 if (der == NULL) 337 return 0; 338 *der_out = der; 339 *len_out = len; 340 return 1; 341 } 342 343 /* Decode an ASN.1 integer, returning a bignum. */ 344 static BIGNUM * 345 decode_bn_der(const uint8_t *der, size_t len) 346 { 347 ASN1_INTEGER *intval; 348 BIGNUM *bn; 349 350 intval = d2i_ASN1_INTEGER(NULL, &der, len); 351 if (intval == NULL) 352 return NULL; 353 bn = ASN1_INTEGER_to_BN(intval, NULL); 354 ASN1_INTEGER_free(intval); 355 return bn; 356 } 357 358 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 359 360 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 361 static EVP_PKEY * 362 decode_params(const krb5_data *params_der, const char *type) 363 { 364 EVP_PKEY *pkey = NULL; 365 const uint8_t *inptr = (uint8_t *)params_der->data; 366 size_t len = params_der->length; 367 OSSL_DECODER_CTX *dctx; 368 int ok; 369 370 dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "type-specific", type, 371 EVP_PKEY_KEY_PARAMETERS, NULL, NULL); 372 if (dctx == NULL) 373 return NULL; 374 375 ok = OSSL_DECODER_from_data(dctx, &inptr, &len); 376 OSSL_DECODER_CTX_free(dctx); 377 return ok ? pkey : NULL; 378 } 379 380 static EVP_PKEY * 381 decode_dh_params(const krb5_data *params_der) 382 { 383 return decode_params(params_der, "DHX"); 384 } 385 386 #else 387 388 static EVP_PKEY * 389 decode_dh_params(const krb5_data *params_der) 390 { 391 const uint8_t *p = (uint8_t *)params_der->data; 392 DH *dh; 393 EVP_PKEY *pkey; 394 395 dh = d2i_DHxparams(NULL, &p, params_der->length); 396 pkey = dh_to_pkey(&dh); 397 DH_free(dh); 398 return pkey; 399 } 400 401 #endif 402 403 static krb5_error_code 404 encode_spki(EVP_PKEY *pkey, krb5_data *spki_out) 405 { 406 krb5_error_code ret = ENOMEM; 407 int len; 408 uint8_t *outptr; 409 410 len = i2d_PUBKEY(pkey, NULL); 411 ret = alloc_data(spki_out, len); 412 if (ret) 413 goto cleanup; 414 outptr = (uint8_t *)spki_out->data; 415 (void)i2d_PUBKEY(pkey, &outptr); 416 417 cleanup: 418 return ret; 419 } 420 421 static EVP_PKEY * 422 decode_spki(const krb5_data *spki) 423 { 424 const uint8_t *inptr = (uint8_t *)spki->data; 425 426 return d2i_PUBKEY(NULL, &inptr, spki->length); 427 } 428 429 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */ 430 431 /* 432 * OpenSSL 1.0 has no DHX support, so we need a custom decoder for RFC 3279 433 * DomainParameters, and we need to use X509_PUBKEY values to marshal 434 * SubjectPublicKeyInfo. 435 */ 436 437 typedef struct { 438 ASN1_BIT_STRING *seed; 439 BIGNUM *counter; 440 } int_dhvparams; 441 442 typedef struct { 443 BIGNUM *p; 444 BIGNUM *q; 445 BIGNUM *g; 446 BIGNUM *j; 447 int_dhvparams *vparams; 448 } int_dhxparams; 449 450 ASN1_SEQUENCE(int_dhvparams) = { 451 ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING), 452 ASN1_SIMPLE(int_dhvparams, counter, BIGNUM) 453 } ASN1_SEQUENCE_END(int_dhvparams); 454 455 ASN1_SEQUENCE(int_dhxparams) = { 456 ASN1_SIMPLE(int_dhxparams, p, BIGNUM), 457 ASN1_SIMPLE(int_dhxparams, g, BIGNUM), 458 ASN1_SIMPLE(int_dhxparams, q, BIGNUM), 459 ASN1_OPT(int_dhxparams, j, BIGNUM), 460 ASN1_OPT(int_dhxparams, vparams, int_dhvparams) 461 } ASN1_SEQUENCE_END(int_dhxparams); 462 463 static EVP_PKEY * 464 decode_dh_params(const krb5_data *params_der) 465 { 466 int_dhxparams *params; 467 DH *dh; 468 EVP_PKEY *pkey; 469 const uint8_t *p; 470 471 dh = DH_new(); 472 if (dh == NULL) 473 return NULL; 474 475 p = (uint8_t *)params_der->data; 476 params = (int_dhxparams *)ASN1_item_d2i(NULL, &p, params_der->length, 477 ASN1_ITEM_rptr(int_dhxparams)); 478 if (params == NULL) { 479 DH_free(dh); 480 return NULL; 481 } 482 483 /* Steal p, q, and g from dhparams for dh. Ignore j and vparams. */ 484 dh->p = params->p; 485 dh->q = params->q; 486 dh->g = params->g; 487 params->p = params->q = params->g = NULL; 488 ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(int_dhxparams)); 489 pkey = dh_to_pkey(&dh); 490 DH_free(dh); 491 return pkey; 492 } 493 494 static krb5_error_code 495 encode_spki(EVP_PKEY *pkey, krb5_data *spki_out) 496 { 497 krb5_error_code ret = ENOMEM; 498 const DH *dh; 499 uint8_t *param_der = NULL, *pubkey_der = NULL, *outptr; 500 int param_der_len, pubkey_der_len, len; 501 X509_PUBKEY pubkey; 502 int_dhxparams dhxparams; 503 X509_ALGOR algor; 504 ASN1_OBJECT algorithm; 505 ASN1_TYPE parameter; 506 ASN1_STRING param_str, pubkey_str; 507 508 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { 509 /* Only DH keys require special encoding. */ 510 len = i2d_PUBKEY(pkey, NULL); 511 ret = alloc_data(spki_out, len); 512 if (ret) 513 goto cleanup; 514 outptr = (uint8_t *)spki_out->data; 515 (void)i2d_PUBKEY(pkey, &outptr); 516 return 0; 517 } 518 519 dh = EVP_PKEY_get0_DH(pkey); 520 if (dh == NULL) 521 goto cleanup; 522 523 dhxparams.p = dh->p; 524 dhxparams.q = dh->q; 525 dhxparams.g = dh->g; 526 dhxparams.j = NULL; 527 dhxparams.vparams = NULL; 528 param_der_len = ASN1_item_i2d((ASN1_VALUE *)&dhxparams, ¶m_der, 529 ASN1_ITEM_rptr(int_dhxparams)); 530 if (param_der_len < 0) 531 goto cleanup; 532 param_str.length = param_der_len; 533 param_str.type = V_ASN1_SEQUENCE; 534 param_str.data = param_der; 535 param_str.flags = 0; 536 parameter.type = V_ASN1_SEQUENCE; 537 parameter.value.sequence = ¶m_str; 538 539 memset(&algorithm, 0, sizeof(algorithm)); 540 algorithm.data = (uint8_t *)dh_oid.data; 541 algorithm.length = dh_oid.length; 542 543 algor.algorithm = &algorithm; 544 algor.parameter = ¶meter; 545 546 if (!encode_bn_der(dh->pub_key, &pubkey_der, &pubkey_der_len)) 547 goto cleanup; 548 pubkey_str.length = pubkey_der_len; 549 pubkey_str.type = V_ASN1_BIT_STRING; 550 pubkey_str.data = pubkey_der; 551 pubkey_str.flags = ASN1_STRING_FLAG_BITS_LEFT; 552 553 pubkey.algor = &algor; 554 pubkey.public_key = &pubkey_str; 555 len = i2d_X509_PUBKEY(&pubkey, NULL); 556 if (len < 0) 557 goto cleanup; 558 ret = alloc_data(spki_out, len); 559 if (ret) 560 goto cleanup; 561 outptr = (uint8_t *)spki_out->data; 562 i2d_X509_PUBKEY(&pubkey, &outptr); 563 564 cleanup: 565 OPENSSL_free(param_der); 566 free(pubkey_der); 567 return ret; 568 } 569 570 static EVP_PKEY * 571 decode_spki(const krb5_data *spki) 572 { 573 X509_PUBKEY *pubkey = NULL; 574 const uint8_t *inptr; 575 DH *dh; 576 EVP_PKEY *pkey = NULL, *pkey_ret = NULL; 577 const ASN1_STRING *params; 578 const ASN1_BIT_STRING *public_key; 579 krb5_data d; 580 581 inptr = (uint8_t *)spki->data; 582 pubkey = d2i_X509_PUBKEY(NULL, &inptr, spki->length); 583 if (pubkey == NULL) 584 goto cleanup; 585 586 if (OBJ_cmp(pubkey->algor->algorithm, OBJ_nid2obj(NID_dhKeyAgreement))) { 587 /* This is not a DH key, so we don't need special decoding. */ 588 X509_PUBKEY_free(pubkey); 589 inptr = (uint8_t *)spki->data; 590 return d2i_PUBKEY(NULL, &inptr, spki->length); 591 } 592 593 if (pubkey->algor->parameter->type != V_ASN1_SEQUENCE) 594 goto cleanup; 595 params = pubkey->algor->parameter->value.sequence; 596 d = make_data(params->data, params->length); 597 pkey = decode_dh_params(&d); 598 if (pkey == NULL) 599 goto cleanup; 600 dh = EVP_PKEY_get0_DH(pkey); 601 if (dh == NULL) 602 goto cleanup; 603 public_key = pubkey->public_key; 604 dh->pub_key = decode_bn_der(public_key->data, public_key->length); 605 if (dh->pub_key == NULL) 606 goto cleanup; 607 608 pkey_ret = pkey; 609 pkey = NULL; 610 611 cleanup: 612 X509_PUBKEY_free(pubkey); 613 EVP_PKEY_free(pkey); 614 return pkey_ret; 615 } 616 617 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ 618 619 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 620 621 static EVP_PKEY * 622 decode_ec_params(const krb5_data *params_der) 623 { 624 return decode_params(params_der, "EC"); 625 } 626 627 #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 628 629 static EVP_PKEY * 630 decode_ec_params(const krb5_data *params_der) 631 { 632 const uint8_t *p = (uint8_t *)params_der->data; 633 EC_KEY *eckey; 634 EVP_PKEY *pkey; 635 636 eckey = d2i_ECParameters(NULL, &p, params_der->length); 637 if (eckey == NULL) 638 return NULL; 639 pkey = EVP_PKEY_new(); 640 if (pkey != NULL) { 641 if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { 642 EVP_PKEY_free(pkey); 643 pkey = NULL; 644 } 645 } 646 EC_KEY_free(eckey); 647 return pkey; 648 } 649 650 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 651 652 /* Attempt to specify padded Diffie-Hellman result derivation. Don't error out 653 * if this fails since we also detect short results and adjust them. */ 654 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 655 static void 656 set_padded_derivation(EVP_PKEY_CTX *ctx) 657 { 658 EVP_PKEY_CTX_set_dh_pad(ctx, 1); 659 } 660 #elif OPENSSL_VERSION_NUMBER >= 0x10100000L 661 static void 662 set_padded_derivation(EVP_PKEY_CTX *ctx) 663 { 664 /* We would use EVP_PKEY_CTX_set_dh_pad() but it doesn't work with DHX. */ 665 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, 666 EVP_PKEY_CTRL_DH_PAD, 1, NULL); 667 } 668 #else 669 static void 670 set_padded_derivation(EVP_PKEY_CTX *ctx) 671 { 672 /* There's no support for padded derivation in 1.0. */ 673 } 674 #endif 675 676 static int 677 dh_result(EVP_PKEY *pkey, EVP_PKEY *peer, 678 uint8_t **result_out, unsigned int *len_out) 679 { 680 EVP_PKEY_CTX *derive_ctx = NULL; 681 int ok = 0; 682 uint8_t *buf = NULL; 683 size_t len, result_size; 684 krb5_boolean ecc = (EVP_PKEY_id(pkey) == EVP_PKEY_EC); 685 686 *result_out = NULL; 687 *len_out = 0; 688 689 derive_ctx = EVP_PKEY_CTX_new(pkey, NULL); 690 if (derive_ctx == NULL) 691 goto cleanup; 692 if (EVP_PKEY_derive_init(derive_ctx) <= 0) 693 goto cleanup; 694 if (!ecc) 695 set_padded_derivation(derive_ctx); 696 if (EVP_PKEY_derive_set_peer(derive_ctx, peer) <= 0) 697 goto cleanup; 698 699 if (ecc) { 700 if (EVP_PKEY_derive(derive_ctx, NULL, &result_size) <= 0) 701 goto cleanup; 702 } else { 703 /* 704 * For finite-field Diffie-Hellman we must ensure that the result 705 * matches the key size (normally through padded derivation, but that 706 * isn't supported by OpenSSL 1.0 so we must check). 707 */ 708 result_size = EVP_PKEY_get_size(pkey); 709 } 710 buf = malloc(result_size); 711 if (buf == NULL) 712 goto cleanup; 713 len = result_size; 714 if (EVP_PKEY_derive(derive_ctx, buf, &len) <= 0) 715 goto cleanup; 716 717 /* If we couldn't specify padded derivation for finite-field DH we may need 718 * to fix up the result by right-shifting it within the buffer. */ 719 if (len < result_size) { 720 memmove(buf + (result_size - len), buf, len); 721 memset(buf, 0, result_size - len); 722 } 723 724 ok = 1; 725 *result_out = buf; 726 *len_out = result_size; 727 buf = NULL; 728 729 cleanup: 730 EVP_PKEY_CTX_free(derive_ctx); 731 free(buf); 732 return ok; 733 } 734 735 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 736 static int 737 dh_pubkey_der(EVP_PKEY *pkey, uint8_t **pubkey_out, unsigned int *len_out) 738 { 739 BIGNUM *pubkey_bn = NULL; 740 int len, ok = 0; 741 uint8_t *buf, *outptr; 742 743 if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { 744 len = i2d_PublicKey(pkey, NULL); 745 if (len > 0 && (outptr = buf = malloc(len)) != NULL) { 746 (void)i2d_PublicKey(pkey, &outptr); 747 ok = 1; 748 } 749 } else { 750 if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pubkey_bn)) 751 return 0; 752 ok = encode_bn_der(pubkey_bn, &buf, &len); 753 BN_free(pubkey_bn); 754 } 755 if (ok) { 756 *pubkey_out = buf; 757 *len_out = len; 758 } 759 return ok; 760 } 761 #else 762 static int 763 dh_pubkey_der(EVP_PKEY *pkey, uint8_t **pubkey_out, unsigned int *len_out) 764 { 765 const DH *dh; 766 EC_KEY *eckey; /* can be const when OpenSSL 1.0 dropped */ 767 const BIGNUM *pubkey_bn; 768 uint8_t *buf, *outptr; 769 int len; 770 771 dh = EVP_PKEY_get0_DH(pkey); 772 if (dh != NULL) { 773 DH_get0_key(dh, &pubkey_bn, NULL); 774 if (!encode_bn_der(pubkey_bn, &buf, &len)) 775 return 0; 776 *pubkey_out = buf; 777 *len_out = len; 778 return 1; 779 } 780 781 eckey = EVP_PKEY_get0_EC_KEY(pkey); 782 if (eckey != NULL) { 783 len = i2o_ECPublicKey(eckey, NULL); 784 if (len > 0 && (outptr = buf = malloc(len)) != NULL) { 785 (void)i2o_ECPublicKey(eckey, &outptr); 786 *pubkey_out = buf; 787 *len_out = len; 788 return 1; 789 } 790 } 791 792 return 0; 793 } 794 #endif 795 796 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 797 /* OpenSSL 1.1 and later will copy the q parameter when generating keys. */ 798 static int 799 copy_q_openssl10(EVP_PKEY *src, EVP_PKEY *dest) 800 { 801 return 1; 802 } 803 #else 804 /* OpenSSL 1.0 won't copy the q parameter, so we have to do it. */ 805 static int 806 copy_q_openssl10(EVP_PKEY *src, EVP_PKEY *dest) 807 { 808 DH *dhsrc = EVP_PKEY_get0_DH(src), *dhdest = EVP_PKEY_get0_DH(dest); 809 810 if (dhsrc == NULL || dhsrc->q == NULL || dhdest == NULL) 811 return 0; 812 if (dhdest->q != NULL) 813 return 1; 814 dhdest->q = BN_dup(dhsrc->q); 815 return dhdest->q != NULL; 816 } 817 #endif 818 819 static EVP_PKEY * 820 generate_dh_pkey(EVP_PKEY *params) 821 { 822 EVP_PKEY_CTX *ctx = NULL; 823 EVP_PKEY *pkey = NULL; 824 825 ctx = EVP_PKEY_CTX_new(params, NULL); 826 if (ctx == NULL) 827 goto cleanup; 828 if (EVP_PKEY_keygen_init(ctx) <= 0) 829 goto cleanup; 830 if (EVP_PKEY_keygen(ctx, &pkey) <= 0) 831 goto cleanup; 832 if (EVP_PKEY_get_base_id(pkey) == EVP_PKEY_DH && 833 !copy_q_openssl10(params, pkey)) { 834 EVP_PKEY_free(pkey); 835 pkey = NULL; 836 } 837 838 cleanup: 839 EVP_PKEY_CTX_free(ctx); 840 return pkey; 841 } 842 843 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 844 845 static EVP_PKEY * 846 compose_dh_pkey(EVP_PKEY *params, const uint8_t *pubkey_der, size_t der_len) 847 { 848 EVP_PKEY *pkey = NULL, *pkey_ret = NULL; 849 BIGNUM *pubkey_bn = NULL; 850 uint8_t *pubkey_bin = NULL; 851 int binlen; 852 853 pkey = EVP_PKEY_dup(params); 854 if (pkey == NULL) 855 goto cleanup; 856 857 if (EVP_PKEY_id(params) == EVP_PKEY_EC) { 858 if (d2i_PublicKey(EVP_PKEY_id(params), &pkey, &pubkey_der, 859 der_len) == NULL) 860 goto cleanup; 861 } else { 862 pubkey_bn = decode_bn_der(pubkey_der, der_len); 863 if (pubkey_bn == NULL) 864 goto cleanup; 865 binlen = EVP_PKEY_get_size(pkey); 866 pubkey_bin = malloc(binlen); 867 if (pubkey_bin == NULL) 868 goto cleanup; 869 if (BN_bn2binpad(pubkey_bn, pubkey_bin, binlen) != binlen) 870 goto cleanup; 871 if (EVP_PKEY_set1_encoded_public_key(pkey, pubkey_bin, binlen) != 1) 872 goto cleanup; 873 } 874 875 pkey_ret = pkey; 876 pkey = NULL; 877 878 cleanup: 879 EVP_PKEY_free(pkey); 880 BN_free(pubkey_bn); 881 free(pubkey_bin); 882 return pkey_ret; 883 } 884 885 #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 886 887 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 888 static DH * 889 dup_dh_params(DH *src) 890 { 891 return DHparams_dup(src); 892 } 893 #else 894 /* DHparams_dup() won't copy q in OpenSSL 1.0. */ 895 static DH * 896 dup_dh_params(DH *src) 897 { 898 DH *dh; 899 900 dh = DH_new(); 901 if (dh == NULL) 902 return NULL; 903 dh->p = BN_dup(src->p); 904 dh->q = BN_dup(src->q); 905 dh->g = BN_dup(src->g); 906 if (dh->p == NULL || dh->q == NULL || dh->g == NULL) { 907 DH_free(dh); 908 return NULL; 909 } 910 return dh; 911 } 912 #endif 913 914 static EVP_PKEY * 915 compose_dh_pkey(EVP_PKEY *params, const uint8_t *pubkey_der, size_t der_len) 916 { 917 DH *dhparams, *dh = NULL; 918 EVP_PKEY *pkey = NULL, *pkey_ret = NULL; 919 BIGNUM *pubkey_bn = NULL; 920 EC_KEY *params_eckey, *eckey = NULL; 921 const EC_GROUP *group; 922 923 if (EVP_PKEY_id(params) == EVP_PKEY_EC) { 924 /* We would like to use EVP_PKEY_copy_parameters() and d2i_PublicKey(), 925 * but the latter is broken in OpenSSL 1.1.0-1.1.1a for EC keys. */ 926 params_eckey = EVP_PKEY_get0_EC_KEY(params); 927 if (params_eckey == NULL) 928 goto cleanup; 929 group = EC_KEY_get0_group(params_eckey); 930 eckey = EC_KEY_new(); 931 if (eckey == NULL) 932 goto cleanup; 933 if (!EC_KEY_set_group(eckey, group)) 934 goto cleanup; 935 if (o2i_ECPublicKey(&eckey, &pubkey_der, der_len) == NULL) 936 goto cleanup; 937 pkey = EVP_PKEY_new(); 938 if (pkey == NULL) 939 return NULL; 940 if (!EVP_PKEY_assign(pkey, EVP_PKEY_EC, eckey)) { 941 EVP_PKEY_free(pkey); 942 return NULL; 943 } 944 eckey = NULL; 945 } else { 946 pubkey_bn = decode_bn_der(pubkey_der, der_len); 947 if (pubkey_bn == NULL) 948 goto cleanup; 949 950 dhparams = EVP_PKEY_get0_DH(params); 951 if (dhparams == NULL) 952 goto cleanup; 953 dh = dup_dh_params(dhparams); 954 if (dh == NULL) 955 goto cleanup; 956 if (!DH_set0_key(dh, pubkey_bn, NULL)) 957 goto cleanup; 958 pubkey_bn = NULL; 959 960 pkey = dh_to_pkey(&dh); 961 } 962 963 pkey_ret = pkey; 964 pkey = NULL; 965 966 cleanup: 967 BN_free(pubkey_bn); 968 DH_free(dh); 969 EC_KEY_free(eckey); 970 EVP_PKEY_free(pkey); 971 return pkey_ret; 972 } 973 974 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 975 976 #ifndef WITHOUT_PKC11 977 static struct pkcs11_errstrings { 978 CK_RV code; 979 char *text; 980 } pkcs11_errstrings[] = { 981 { 0x0, "ok" }, 982 { 0x1, "cancel" }, 983 { 0x2, "host memory" }, 984 { 0x3, "slot id invalid" }, 985 { 0x5, "general error" }, 986 { 0x6, "function failed" }, 987 { 0x7, "arguments bad" }, 988 { 0x8, "no event" }, 989 { 0x9, "need to create threads" }, 990 { 0xa, "cant lock" }, 991 { 0x10, "attribute read only" }, 992 { 0x11, "attribute sensitive" }, 993 { 0x12, "attribute type invalid" }, 994 { 0x13, "attribute value invalid" }, 995 { 0x20, "data invalid" }, 996 { 0x21, "data len range" }, 997 { 0x30, "device error" }, 998 { 0x31, "device memory" }, 999 { 0x32, "device removed" }, 1000 { 0x40, "encrypted data invalid" }, 1001 { 0x41, "encrypted data len range" }, 1002 { 0x50, "function canceled" }, 1003 { 0x51, "function not parallel" }, 1004 { 0x54, "function not supported" }, 1005 { 0x60, "key handle invalid" }, 1006 { 0x62, "key size range" }, 1007 { 0x63, "key type inconsistent" }, 1008 { 0x64, "key not needed" }, 1009 { 0x65, "key changed" }, 1010 { 0x66, "key needed" }, 1011 { 0x67, "key indigestible" }, 1012 { 0x68, "key function not permitted" }, 1013 { 0x69, "key not wrappable" }, 1014 { 0x6a, "key unextractable" }, 1015 { 0x70, "mechanism invalid" }, 1016 { 0x71, "mechanism param invalid" }, 1017 { 0x82, "object handle invalid" }, 1018 { 0x90, "operation active" }, 1019 { 0x91, "operation not initialized" }, 1020 { 0xa0, "pin incorrect" }, 1021 { 0xa1, "pin invalid" }, 1022 { 0xa2, "pin len range" }, 1023 { 0xa3, "pin expired" }, 1024 { 0xa4, "pin locked" }, 1025 { 0xb0, "session closed" }, 1026 { 0xb1, "session count" }, 1027 { 0xb3, "session handle invalid" }, 1028 { 0xb4, "session parallel not supported" }, 1029 { 0xb5, "session read only" }, 1030 { 0xb6, "session exists" }, 1031 { 0xb7, "session read only exists" }, 1032 { 0xb8, "session read write so exists" }, 1033 { 0xc0, "signature invalid" }, 1034 { 0xc1, "signature len range" }, 1035 { 0xd0, "template incomplete" }, 1036 { 0xd1, "template inconsistent" }, 1037 { 0xe0, "token not present" }, 1038 { 0xe1, "token not recognized" }, 1039 { 0xe2, "token write protected" }, 1040 { 0xf0, "unwrapping key handle invalid" }, 1041 { 0xf1, "unwrapping key size range" }, 1042 { 0xf2, "unwrapping key type inconsistent" }, 1043 { 0x100, "user already logged in" }, 1044 { 0x101, "user not logged in" }, 1045 { 0x102, "user pin not initialized" }, 1046 { 0x103, "user type invalid" }, 1047 { 0x104, "user another already logged in" }, 1048 { 0x105, "user too many types" }, 1049 { 0x110, "wrapped key invalid" }, 1050 { 0x112, "wrapped key len range" }, 1051 { 0x113, "wrapping key handle invalid" }, 1052 { 0x114, "wrapping key size range" }, 1053 { 0x115, "wrapping key type inconsistent" }, 1054 { 0x120, "random seed not supported" }, 1055 { 0x121, "random no rng" }, 1056 { 0x130, "domain params invalid" }, 1057 { 0x150, "buffer too small" }, 1058 { 0x160, "saved state invalid" }, 1059 { 0x170, "information sensitive" }, 1060 { 0x180, "state unsaveable" }, 1061 { 0x190, "cryptoki not initialized" }, 1062 { 0x191, "cryptoki already initialized" }, 1063 { 0x1a0, "mutex bad" }, 1064 { 0x1a1, "mutex not locked" }, 1065 { 0x200, "function rejected" }, 1066 { -1, NULL } 1067 }; 1068 #endif 1069 1070 MAKE_INIT_FUNCTION(pkinit_openssl_init); 1071 1072 static krb5_error_code oerr(krb5_context context, krb5_error_code code, 1073 const char *fmt, ...) 1074 #if !defined(__cplusplus) && (__GNUC__ > 2) 1075 __attribute__((__format__(__printf__, 3, 4))) 1076 #endif 1077 ; 1078 1079 /* 1080 * Set an error string containing the formatted arguments and the first pending 1081 * OpenSSL error. Write the formatted arguments and all pending OpenSSL error 1082 * messages to the trace log. Return code, or KRB5KDC_ERR_PREAUTH_FAILED if 1083 * code is 0. 1084 */ 1085 static krb5_error_code 1086 oerr(krb5_context context, krb5_error_code code, const char *fmt, ...) 1087 { 1088 unsigned long err; 1089 va_list ap; 1090 char *str, buf[128]; 1091 int r; 1092 1093 if (!code) 1094 code = KRB5KDC_ERR_PREAUTH_FAILED; 1095 1096 va_start(ap, fmt); 1097 r = vasprintf(&str, fmt, ap); 1098 va_end(ap); 1099 if (r < 0) 1100 return code; 1101 1102 err = ERR_peek_error(); 1103 if (err) { 1104 krb5_set_error_message(context, code, _("%s: %s"), str, 1105 ERR_reason_error_string(err)); 1106 } else { 1107 krb5_set_error_message(context, code, "%s", str); 1108 } 1109 1110 TRACE_PKINIT_OPENSSL_ERROR(context, str); 1111 while ((err = ERR_get_error()) != 0) { 1112 ERR_error_string_n(err, buf, sizeof(buf)); 1113 TRACE_PKINIT_OPENSSL_ERROR(context, buf); 1114 } 1115 1116 free(str); 1117 return code; 1118 } 1119 1120 /* 1121 * Set an appropriate error string containing msg for a certificate 1122 * verification failure from certctx. Write the message and all pending 1123 * OpenSSL error messages to the trace log. Return code, or 1124 * KRB5KDC_ERR_PREAUTH_FAILED if code is 0. 1125 */ 1126 static krb5_error_code 1127 oerr_cert(krb5_context context, krb5_error_code code, X509_STORE_CTX *certctx, 1128 const char *msg) 1129 { 1130 int depth = X509_STORE_CTX_get_error_depth(certctx); 1131 int err = X509_STORE_CTX_get_error(certctx); 1132 const char *errstr = X509_verify_cert_error_string(err); 1133 1134 return oerr(context, code, _("%s (depth %d): %s"), msg, depth, errstr); 1135 } 1136 1137 krb5_error_code 1138 pkinit_init_plg_crypto(krb5_context context, 1139 pkinit_plg_crypto_context *cryptoctx) 1140 { 1141 krb5_error_code retval = ENOMEM; 1142 pkinit_plg_crypto_context ctx = NULL; 1143 1144 (void)CALL_INIT_FUNCTION(pkinit_openssl_init); 1145 1146 ctx = malloc(sizeof(*ctx)); 1147 if (ctx == NULL) 1148 goto out; 1149 memset(ctx, 0, sizeof(*ctx)); 1150 1151 pkiDebug("%s: initializing openssl crypto context at %p\n", 1152 __FUNCTION__, ctx); 1153 retval = pkinit_init_pkinit_oids(ctx); 1154 if (retval) 1155 goto out; 1156 1157 retval = pkinit_init_dh_params(context, ctx); 1158 if (retval) 1159 goto out; 1160 1161 *cryptoctx = ctx; 1162 1163 out: 1164 if (retval && ctx != NULL) 1165 pkinit_fini_plg_crypto(ctx); 1166 1167 return retval; 1168 } 1169 1170 void 1171 pkinit_fini_plg_crypto(pkinit_plg_crypto_context cryptoctx) 1172 { 1173 pkiDebug("%s: freeing context at %p\n", __FUNCTION__, cryptoctx); 1174 1175 if (cryptoctx == NULL) 1176 return; 1177 pkinit_fini_pkinit_oids(cryptoctx); 1178 pkinit_fini_dh_params(cryptoctx); 1179 free(cryptoctx); 1180 } 1181 1182 krb5_error_code 1183 pkinit_init_identity_crypto(pkinit_identity_crypto_context *idctx) 1184 { 1185 krb5_error_code retval = ENOMEM; 1186 pkinit_identity_crypto_context ctx = NULL; 1187 1188 ctx = malloc(sizeof(*ctx)); 1189 if (ctx == NULL) 1190 goto out; 1191 memset(ctx, 0, sizeof(*ctx)); 1192 1193 ctx->identity = NULL; 1194 1195 retval = pkinit_init_certs(ctx); 1196 if (retval) 1197 goto out; 1198 1199 retval = pkinit_init_pkcs11(ctx); 1200 if (retval) 1201 goto out; 1202 1203 pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx); 1204 *idctx = ctx; 1205 1206 out: 1207 if (retval) { 1208 if (ctx) 1209 pkinit_fini_identity_crypto(ctx); 1210 } 1211 1212 return retval; 1213 } 1214 1215 void 1216 pkinit_fini_identity_crypto(pkinit_identity_crypto_context idctx) 1217 { 1218 if (idctx == NULL) 1219 return; 1220 1221 pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, idctx); 1222 if (idctx->deferred_ids != NULL) 1223 pkinit_free_deferred_ids(idctx->deferred_ids); 1224 free(idctx->identity); 1225 pkinit_fini_certs(idctx); 1226 pkinit_fini_pkcs11(idctx); 1227 free(idctx); 1228 } 1229 1230 krb5_error_code 1231 pkinit_init_req_crypto(pkinit_req_crypto_context *cryptoctx) 1232 { 1233 krb5_error_code retval = ENOMEM; 1234 pkinit_req_crypto_context ctx = NULL; 1235 1236 ctx = malloc(sizeof(*ctx)); 1237 if (ctx == NULL) 1238 goto out; 1239 memset(ctx, 0, sizeof(*ctx)); 1240 1241 ctx->client_pkey = NULL; 1242 ctx->received_cert = NULL; 1243 1244 *cryptoctx = ctx; 1245 1246 pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx); 1247 retval = 0; 1248 out: 1249 if (retval) 1250 free(ctx); 1251 1252 return retval; 1253 } 1254 1255 void 1256 pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx) 1257 { 1258 if (req_cryptoctx == NULL) 1259 return; 1260 1261 pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, req_cryptoctx); 1262 EVP_PKEY_free(req_cryptoctx->client_pkey); 1263 X509_free(req_cryptoctx->received_cert); 1264 1265 free(req_cryptoctx); 1266 } 1267 1268 static krb5_error_code 1269 pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx) 1270 { 1271 ctx->id_pkinit_san = OBJ_txt2obj("1.3.6.1.5.2.2", 1); 1272 if (ctx->id_pkinit_san == NULL) 1273 return ENOMEM; 1274 1275 ctx->id_pkinit_authData = OBJ_txt2obj("1.3.6.1.5.2.3.1", 1); 1276 if (ctx->id_pkinit_authData == NULL) 1277 return ENOMEM; 1278 1279 ctx->id_pkinit_DHKeyData = OBJ_txt2obj("1.3.6.1.5.2.3.2", 1); 1280 if (ctx->id_pkinit_DHKeyData == NULL) 1281 return ENOMEM; 1282 1283 ctx->id_pkinit_rkeyData = OBJ_txt2obj("1.3.6.1.5.2.3.3", 1); 1284 if (ctx->id_pkinit_rkeyData == NULL) 1285 return ENOMEM; 1286 1287 ctx->id_pkinit_KPClientAuth = OBJ_txt2obj("1.3.6.1.5.2.3.4", 1); 1288 if (ctx->id_pkinit_KPClientAuth == NULL) 1289 return ENOMEM; 1290 1291 ctx->id_pkinit_KPKdc = OBJ_txt2obj("1.3.6.1.5.2.3.5", 1); 1292 if (ctx->id_pkinit_KPKdc == NULL) 1293 return ENOMEM; 1294 1295 ctx->id_ms_kp_sc_logon = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.2", 1); 1296 if (ctx->id_ms_kp_sc_logon == NULL) 1297 return ENOMEM; 1298 1299 ctx->id_ms_san_upn = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1); 1300 if (ctx->id_ms_san_upn == NULL) 1301 return ENOMEM; 1302 1303 ctx->id_kp_serverAuth = OBJ_txt2obj("1.3.6.1.5.5.7.3.1", 1); 1304 if (ctx->id_kp_serverAuth == NULL) 1305 return ENOMEM; 1306 1307 return 0; 1308 } 1309 1310 static krb5_error_code 1311 get_cert(char *filename, X509 **retcert) 1312 { 1313 X509 *cert = NULL; 1314 BIO *tmp = NULL; 1315 int code; 1316 krb5_error_code retval; 1317 1318 if (filename == NULL || retcert == NULL) 1319 return EINVAL; 1320 1321 *retcert = NULL; 1322 1323 tmp = BIO_new(BIO_s_file()); 1324 if (tmp == NULL) 1325 return ENOMEM; 1326 1327 code = BIO_read_filename(tmp, filename); 1328 if (code == 0) { 1329 retval = errno; 1330 goto cleanup; 1331 } 1332 1333 cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL); 1334 if (cert == NULL) { 1335 retval = EIO; 1336 pkiDebug("failed to read certificate from %s\n", filename); 1337 goto cleanup; 1338 } 1339 *retcert = cert; 1340 retval = 0; 1341 cleanup: 1342 if (tmp != NULL) 1343 BIO_free(tmp); 1344 return retval; 1345 } 1346 1347 struct get_key_cb_data { 1348 krb5_context context; 1349 pkinit_identity_crypto_context id_cryptoctx; 1350 const char *fsname; 1351 char *filename; 1352 const char *password; 1353 }; 1354 1355 static int 1356 get_key_cb(char *buf, int size, int rwflag, void *userdata) 1357 { 1358 struct get_key_cb_data *data = userdata; 1359 pkinit_identity_crypto_context id_cryptoctx; 1360 krb5_data rdat; 1361 krb5_prompt kprompt; 1362 krb5_prompt_type prompt_type; 1363 krb5_error_code retval; 1364 char *prompt; 1365 1366 if (data->id_cryptoctx->defer_id_prompt) { 1367 /* Supply the identity name to be passed to a responder callback. */ 1368 pkinit_set_deferred_id(&data->id_cryptoctx->deferred_ids, 1369 data->fsname, 0, NULL); 1370 return -1; 1371 } 1372 if (data->password == NULL) { 1373 /* We don't already have a password to use, so prompt for one. */ 1374 if (data->id_cryptoctx->prompter == NULL) 1375 return -1; 1376 if (asprintf(&prompt, "%s %s", _("Pass phrase for"), 1377 data->filename) < 0) 1378 return -1; 1379 rdat.data = buf; 1380 rdat.length = size; 1381 kprompt.prompt = prompt; 1382 kprompt.hidden = 1; 1383 kprompt.reply = &rdat; 1384 prompt_type = KRB5_PROMPT_TYPE_PREAUTH; 1385 1386 /* PROMPTER_INVOCATION */ 1387 k5int_set_prompt_types(data->context, &prompt_type); 1388 id_cryptoctx = data->id_cryptoctx; 1389 retval = (data->id_cryptoctx->prompter)(data->context, 1390 id_cryptoctx->prompter_data, 1391 NULL, NULL, 1, &kprompt); 1392 k5int_set_prompt_types(data->context, 0); 1393 free(prompt); 1394 if (retval != 0) 1395 return -1; 1396 } else { 1397 /* Just use the already-supplied password. */ 1398 rdat.length = strlen(data->password); 1399 if ((int)rdat.length >= size) 1400 return -1; 1401 snprintf(buf, size, "%s", data->password); 1402 } 1403 return (int)rdat.length; 1404 } 1405 1406 static krb5_error_code 1407 get_key(krb5_context context, pkinit_identity_crypto_context id_cryptoctx, 1408 char *filename, const char *fsname, EVP_PKEY **retkey, 1409 const char *password) 1410 { 1411 EVP_PKEY *pkey = NULL; 1412 BIO *tmp = NULL; 1413 struct get_key_cb_data cb_data; 1414 int code; 1415 krb5_error_code retval; 1416 1417 if (filename == NULL || retkey == NULL) 1418 return EINVAL; 1419 1420 tmp = BIO_new(BIO_s_file()); 1421 if (tmp == NULL) 1422 return ENOMEM; 1423 1424 code = BIO_read_filename(tmp, filename); 1425 if (code == 0) { 1426 retval = errno; 1427 goto cleanup; 1428 } 1429 cb_data.context = context; 1430 cb_data.id_cryptoctx = id_cryptoctx; 1431 cb_data.filename = filename; 1432 cb_data.fsname = fsname; 1433 cb_data.password = password; 1434 pkey = PEM_read_bio_PrivateKey(tmp, NULL, get_key_cb, &cb_data); 1435 if (pkey == NULL && !id_cryptoctx->defer_id_prompt) { 1436 retval = EIO; 1437 pkiDebug("failed to read private key from %s\n", filename); 1438 goto cleanup; 1439 } 1440 *retkey = pkey; 1441 retval = 0; 1442 cleanup: 1443 if (tmp != NULL) 1444 BIO_free(tmp); 1445 return retval; 1446 } 1447 1448 static void 1449 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx) 1450 { 1451 if (ctx == NULL) 1452 return; 1453 ASN1_OBJECT_free(ctx->id_pkinit_san); 1454 ASN1_OBJECT_free(ctx->id_pkinit_authData); 1455 ASN1_OBJECT_free(ctx->id_pkinit_DHKeyData); 1456 ASN1_OBJECT_free(ctx->id_pkinit_rkeyData); 1457 ASN1_OBJECT_free(ctx->id_pkinit_KPClientAuth); 1458 ASN1_OBJECT_free(ctx->id_pkinit_KPKdc); 1459 ASN1_OBJECT_free(ctx->id_ms_kp_sc_logon); 1460 ASN1_OBJECT_free(ctx->id_ms_san_upn); 1461 ASN1_OBJECT_free(ctx->id_kp_serverAuth); 1462 } 1463 1464 static int 1465 try_import_group(krb5_context context, const krb5_data *params, 1466 const char *name, krb5_boolean ec, EVP_PKEY **pkey_out) 1467 { 1468 *pkey_out = ec ? decode_ec_params(params) : decode_dh_params(params); 1469 if (*pkey_out == NULL) 1470 TRACE_PKINIT_DH_GROUP_UNAVAILABLE(context, name); 1471 return (*pkey_out != NULL) ? 1 : 0; 1472 } 1473 1474 static krb5_error_code 1475 pkinit_init_dh_params(krb5_context context, pkinit_plg_crypto_context plgctx) 1476 { 1477 int n = 0; 1478 1479 n += try_import_group(context, &oakley_1024, "MODP 2 (1024-bit)", FALSE, 1480 &plgctx->dh_1024); 1481 n += try_import_group(context, &oakley_2048, "MODP 14 (2048-bit)", FALSE, 1482 &plgctx->dh_2048); 1483 n += try_import_group(context, &oakley_4096, "MODP 16 (4096-bit)", FALSE, 1484 &plgctx->dh_4096); 1485 n += try_import_group(context, &ec_p256, "P-256", TRUE, &plgctx->ec_p256); 1486 n += try_import_group(context, &ec_p384, "P-384", TRUE, &plgctx->ec_p384); 1487 n += try_import_group(context, &ec_p521, "P-521", TRUE, &plgctx->ec_p521); 1488 1489 if (n == 0) { 1490 pkinit_fini_dh_params(plgctx); 1491 k5_setmsg(context, ENOMEM, 1492 _("PKINIT cannot initialize any key exchange groups")); 1493 return ENOMEM; 1494 } 1495 1496 return 0; 1497 } 1498 1499 static void 1500 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx) 1501 { 1502 EVP_PKEY_free(plgctx->dh_1024); 1503 EVP_PKEY_free(plgctx->dh_2048); 1504 EVP_PKEY_free(plgctx->dh_4096); 1505 EVP_PKEY_free(plgctx->ec_p256); 1506 EVP_PKEY_free(plgctx->ec_p384); 1507 EVP_PKEY_free(plgctx->ec_p521); 1508 plgctx->dh_1024 = plgctx->dh_2048 = plgctx->dh_4096 = NULL; 1509 plgctx->ec_p256 = plgctx->ec_p384 = plgctx->ec_p521 = NULL; 1510 } 1511 1512 static krb5_error_code 1513 pkinit_init_certs(pkinit_identity_crypto_context ctx) 1514 { 1515 krb5_error_code retval = ENOMEM; 1516 int i; 1517 1518 for (i = 0; i < MAX_CREDS_ALLOWED; i++) 1519 ctx->creds[i] = NULL; 1520 ctx->my_cert = NULL; 1521 ctx->my_key = NULL; 1522 ctx->trustedCAs = NULL; 1523 ctx->intermediateCAs = NULL; 1524 ctx->revoked = NULL; 1525 1526 retval = 0; 1527 return retval; 1528 } 1529 1530 static void 1531 pkinit_fini_certs(pkinit_identity_crypto_context ctx) 1532 { 1533 if (ctx == NULL) 1534 return; 1535 1536 if (ctx->my_cert != NULL) 1537 X509_free(ctx->my_cert); 1538 1539 if (ctx->my_key != NULL) 1540 EVP_PKEY_free(ctx->my_key); 1541 1542 if (ctx->trustedCAs != NULL) 1543 sk_X509_pop_free(ctx->trustedCAs, X509_free); 1544 1545 if (ctx->intermediateCAs != NULL) 1546 sk_X509_pop_free(ctx->intermediateCAs, X509_free); 1547 1548 if (ctx->revoked != NULL) 1549 sk_X509_CRL_pop_free(ctx->revoked, X509_CRL_free); 1550 } 1551 1552 static krb5_error_code 1553 pkinit_init_pkcs11(pkinit_identity_crypto_context ctx) 1554 { 1555 krb5_error_code retval = ENOMEM; 1556 1557 #ifndef WITHOUT_PKCS11 1558 ctx->p11_module_name = strdup(PKCS11_MODNAME); 1559 if (ctx->p11_module_name == NULL) 1560 return retval; 1561 ctx->p11_module = NULL; 1562 ctx->slotid = PK_NOSLOT; 1563 ctx->token_label = NULL; 1564 ctx->cert_label = NULL; 1565 ctx->session = CK_INVALID_HANDLE; 1566 ctx->p11 = NULL; 1567 #endif 1568 ctx->pkcs11_method = 0; 1569 1570 retval = 0; 1571 return retval; 1572 } 1573 1574 static void 1575 pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx) 1576 { 1577 #ifndef WITHOUT_PKCS11 1578 if (ctx == NULL) 1579 return; 1580 1581 if (ctx->p11 != NULL) { 1582 if (ctx->session != CK_INVALID_HANDLE) { 1583 ctx->p11->C_CloseSession(ctx->session); 1584 ctx->session = CK_INVALID_HANDLE; 1585 } 1586 ctx->p11->C_Finalize(NULL_PTR); 1587 ctx->p11 = NULL; 1588 } 1589 if (ctx->p11_module != NULL) { 1590 krb5int_close_plugin(ctx->p11_module); 1591 ctx->p11_module = NULL; 1592 } 1593 free(ctx->p11_module_name); 1594 free(ctx->token_label); 1595 free(ctx->cert_id); 1596 free(ctx->cert_label); 1597 ctx->p11_module_name = ctx->token_label = ctx->cert_label = NULL; 1598 ctx->cert_id = NULL; 1599 #endif 1600 } 1601 1602 krb5_error_code 1603 pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx, 1604 krb5_prompter_fct prompter, 1605 void *prompter_data) 1606 { 1607 id_cryptoctx->prompter = prompter; 1608 id_cryptoctx->prompter_data = prompter_data; 1609 1610 return 0; 1611 } 1612 1613 /* Create a CMS ContentInfo of type oid containing the octet string in data. */ 1614 static krb5_error_code 1615 create_contentinfo(krb5_context context, ASN1_OBJECT *oid, 1616 unsigned char *data, size_t data_len, PKCS7 **p7_out) 1617 { 1618 PKCS7 *p7 = NULL; 1619 ASN1_OCTET_STRING *ostr = NULL; 1620 1621 *p7_out = NULL; 1622 1623 ostr = ASN1_OCTET_STRING_new(); 1624 if (ostr == NULL) 1625 goto oom; 1626 if (!ASN1_OCTET_STRING_set(ostr, (unsigned char *)data, data_len)) 1627 goto oom; 1628 1629 p7 = PKCS7_new(); 1630 if (p7 == NULL) 1631 goto oom; 1632 p7->type = OBJ_dup(oid); 1633 if (p7->type == NULL) 1634 goto oom; 1635 1636 p7->d.other = ASN1_TYPE_new(); 1637 if (p7->d.other == NULL) 1638 goto oom; 1639 p7->d.other->type = V_ASN1_OCTET_STRING; 1640 p7->d.other->value.octet_string = ostr; 1641 1642 *p7_out = p7; 1643 return 0; 1644 1645 oom: 1646 if (ostr != NULL) 1647 ASN1_OCTET_STRING_free(ostr); 1648 if (p7 != NULL) 1649 PKCS7_free(p7); 1650 return ENOMEM; 1651 } 1652 1653 krb5_error_code 1654 cms_contentinfo_create(krb5_context context, /* IN */ 1655 pkinit_plg_crypto_context plg_cryptoctx, /* IN */ 1656 pkinit_req_crypto_context req_cryptoctx, /* IN */ 1657 pkinit_identity_crypto_context id_cryptoctx, /* IN */ 1658 int cms_msg_type, 1659 unsigned char *data, unsigned int data_len, 1660 unsigned char **out_data, unsigned int *out_data_len) 1661 { 1662 krb5_error_code retval = ENOMEM; 1663 ASN1_OBJECT *oid; 1664 PKCS7 *p7 = NULL; 1665 unsigned char *p; 1666 1667 /* Pick the correct oid for the eContentInfo. */ 1668 oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type); 1669 if (oid == NULL) 1670 goto cleanup; 1671 retval = create_contentinfo(context, oid, data, data_len, &p7); 1672 if (retval != 0) 1673 goto cleanup; 1674 *out_data_len = i2d_PKCS7(p7, NULL); 1675 if (!(*out_data_len)) { 1676 retval = oerr(context, 0, _("Failed to DER encode PKCS7")); 1677 goto cleanup; 1678 } 1679 retval = ENOMEM; 1680 if ((p = *out_data = malloc(*out_data_len)) == NULL) 1681 goto cleanup; 1682 1683 /* DER encode PKCS7 data */ 1684 retval = i2d_PKCS7(p7, &p); 1685 if (!retval) { 1686 retval = oerr(context, 0, _("Failed to DER encode PKCS7")); 1687 goto cleanup; 1688 } 1689 retval = 0; 1690 cleanup: 1691 if (p7) 1692 PKCS7_free(p7); 1693 return retval; 1694 } 1695 1696 /* Return the name ID of the signature algorithm for cert, assuming that the 1697 * digest used is SHA-256 and the cert uses either an RSA or EC public key. */ 1698 static int 1699 cert_sig_alg(X509 *cert) 1700 { 1701 /* Use X509_get0_pubkey() when OpenSSL 1.0 support is removed. */ 1702 EVP_PKEY *pkey = X509_get_pubkey(cert); 1703 int id; 1704 1705 if (pkey != NULL && EVP_PKEY_get_base_id(pkey) == EVP_PKEY_EC) 1706 id = NID_ecdsa_with_SHA256; 1707 else 1708 id = NID_sha256WithRSAEncryption; 1709 EVP_PKEY_free(pkey); 1710 return id; 1711 } 1712 1713 krb5_error_code 1714 cms_signeddata_create(krb5_context context, 1715 pkinit_plg_crypto_context plg_cryptoctx, 1716 pkinit_req_crypto_context req_cryptoctx, 1717 pkinit_identity_crypto_context id_cryptoctx, 1718 int cms_msg_type, 1719 unsigned char *data, 1720 unsigned int data_len, 1721 unsigned char **signed_data, 1722 unsigned int *signed_data_len) 1723 { 1724 krb5_error_code retval = ENOMEM; 1725 PKCS7 *p7 = NULL, *inner_p7 = NULL; 1726 PKCS7_SIGNED *p7s = NULL; 1727 PKCS7_SIGNER_INFO *p7si = NULL; 1728 unsigned char *p; 1729 STACK_OF(X509) * cert_stack = NULL; 1730 ASN1_OCTET_STRING *digest_attr = NULL; 1731 EVP_MD_CTX *ctx; 1732 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf = NULL; 1733 unsigned int md_len, alen; 1734 STACK_OF(X509_ATTRIBUTE) * sk; 1735 unsigned char *sig = NULL; 1736 unsigned int sig_len = 0; 1737 X509_ALGOR *alg = NULL; 1738 ASN1_OBJECT *oid = NULL, *oid_copy; 1739 int sig_alg_id; 1740 1741 /* Start creating PKCS7 data. */ 1742 if ((p7 = PKCS7_new()) == NULL) 1743 goto cleanup; 1744 p7->type = OBJ_nid2obj(NID_pkcs7_signed); 1745 1746 if ((p7s = PKCS7_SIGNED_new()) == NULL) 1747 goto cleanup; 1748 p7->d.sign = p7s; 1749 if (!ASN1_INTEGER_set(p7s->version, 3)) 1750 goto cleanup; 1751 1752 /* pick the correct oid for the eContentInfo */ 1753 oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type); 1754 if (oid == NULL) 1755 goto cleanup; 1756 1757 if (id_cryptoctx->my_cert != NULL) { 1758 X509_STORE *certstore = NULL; 1759 X509_STORE_CTX *certctx; 1760 STACK_OF(X509) *certstack = NULL; 1761 char buf[DN_BUF_LEN]; 1762 unsigned int i = 0, size = 0; 1763 1764 /* create a cert chain */ 1765 if ((cert_stack = sk_X509_new_null()) == NULL) 1766 goto cleanup; 1767 1768 certstore = X509_STORE_new(); 1769 if (certstore == NULL) 1770 goto cleanup; 1771 pkiDebug("building certificate chain\n"); 1772 X509_STORE_set_verify_cb(certstore, openssl_callback); 1773 certctx = X509_STORE_CTX_new(); 1774 if (certctx == NULL) 1775 goto cleanup; 1776 X509_STORE_CTX_init(certctx, certstore, id_cryptoctx->my_cert, 1777 id_cryptoctx->intermediateCAs); 1778 X509_STORE_CTX_trusted_stack(certctx, id_cryptoctx->trustedCAs); 1779 if (!X509_verify_cert(certctx)) { 1780 retval = oerr_cert(context, 0, certctx, 1781 _("Failed to verify own certificate")); 1782 goto cleanup; 1783 } 1784 certstack = X509_STORE_CTX_get1_chain(certctx); 1785 size = sk_X509_num(certstack); 1786 for (i = 0; i < size - 1; i++) { 1787 X509 *x = sk_X509_value(certstack, i); 1788 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf)); 1789 TRACE_PKINIT_CERT_CHAIN_NAME(context, (int)i, buf); 1790 sk_X509_push(cert_stack, X509_dup(x)); 1791 } 1792 X509_STORE_CTX_free(certctx); 1793 X509_STORE_free(certstore); 1794 sk_X509_pop_free(certstack, X509_free); 1795 1796 p7s->cert = cert_stack; 1797 1798 /* fill-in PKCS7_SIGNER_INFO */ 1799 if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL) 1800 goto cleanup; 1801 if (!ASN1_INTEGER_set(p7si->version, 1)) 1802 goto cleanup; 1803 if (!X509_NAME_set(&p7si->issuer_and_serial->issuer, 1804 X509_get_issuer_name(id_cryptoctx->my_cert))) 1805 goto cleanup; 1806 /* because ASN1_INTEGER_set is used to set a 'long' we will do 1807 * things the ugly way. */ 1808 ASN1_INTEGER_free(p7si->issuer_and_serial->serial); 1809 if (!(p7si->issuer_and_serial->serial = 1810 ASN1_INTEGER_dup(X509_get_serialNumber(id_cryptoctx->my_cert)))) 1811 goto cleanup; 1812 1813 /* will not fill-out EVP_PKEY because it's on the smartcard */ 1814 1815 /* Set digest algs */ 1816 p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha256); 1817 1818 if (p7si->digest_alg->parameter != NULL) 1819 ASN1_TYPE_free(p7si->digest_alg->parameter); 1820 if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL) 1821 goto cleanup; 1822 p7si->digest_alg->parameter->type = V_ASN1_NULL; 1823 1824 /* Set sig algs */ 1825 if (p7si->digest_enc_alg->parameter != NULL) 1826 ASN1_TYPE_free(p7si->digest_enc_alg->parameter); 1827 sig_alg_id = cert_sig_alg(id_cryptoctx->my_cert); 1828 p7si->digest_enc_alg->algorithm = OBJ_nid2obj(sig_alg_id); 1829 if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new())) 1830 goto cleanup; 1831 p7si->digest_enc_alg->parameter->type = V_ASN1_NULL; 1832 1833 /* add signed attributes */ 1834 /* compute sha256 digest over the EncapsulatedContentInfo */ 1835 ctx = EVP_MD_CTX_new(); 1836 if (ctx == NULL) 1837 goto cleanup; 1838 EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); 1839 EVP_DigestUpdate(ctx, data, data_len); 1840 EVP_DigestFinal_ex(ctx, md_data, &md_len); 1841 EVP_MD_CTX_free(ctx); 1842 1843 /* create a message digest attr */ 1844 digest_attr = ASN1_OCTET_STRING_new(); 1845 ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len); 1846 PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest, 1847 V_ASN1_OCTET_STRING, (char *)digest_attr); 1848 1849 /* create a content-type attr */ 1850 oid_copy = OBJ_dup(oid); 1851 if (oid_copy == NULL) 1852 goto cleanup2; 1853 PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, 1854 V_ASN1_OBJECT, oid_copy); 1855 1856 /* create the signature over signed attributes. get DER encoded value */ 1857 /* This is the place where smartcard signature needs to be calculated */ 1858 sk = p7si->auth_attr; 1859 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1860 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 1861 if (abuf == NULL) 1862 goto cleanup2; 1863 1864 retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen, 1865 &sig, &sig_len); 1866 #ifdef DEBUG_SIG 1867 print_buffer(sig, sig_len); 1868 #endif 1869 OPENSSL_free(abuf); 1870 if (retval) 1871 goto cleanup2; 1872 1873 /* Add signature */ 1874 if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig, 1875 (int)sig_len)) { 1876 retval = oerr(context, 0, _("Failed to add digest attribute")); 1877 goto cleanup2; 1878 } 1879 /* adder signer_info to pkcs7 signed */ 1880 if (!PKCS7_add_signer(p7, p7si)) 1881 goto cleanup2; 1882 } /* we have a certificate */ 1883 1884 /* start on adding data to the pkcs7 signed */ 1885 retval = create_contentinfo(context, oid, data, data_len, &inner_p7); 1886 if (p7s->contents != NULL) 1887 PKCS7_free(p7s->contents); 1888 p7s->contents = inner_p7; 1889 1890 *signed_data_len = i2d_PKCS7(p7, NULL); 1891 if (!(*signed_data_len)) { 1892 retval = oerr(context, 0, _("Failed to DER encode PKCS7")); 1893 goto cleanup2; 1894 } 1895 retval = ENOMEM; 1896 if ((p = *signed_data = malloc(*signed_data_len)) == NULL) 1897 goto cleanup2; 1898 1899 /* DER encode PKCS7 data */ 1900 retval = i2d_PKCS7(p7, &p); 1901 if (!retval) { 1902 retval = oerr(context, 0, _("Failed to DER encode PKCS7")); 1903 goto cleanup2; 1904 } 1905 retval = 0; 1906 1907 #ifdef DEBUG_ASN1 1908 if (cms_msg_type == CMS_SIGN_CLIENT) { 1909 print_buffer_bin(*signed_data, *signed_data_len, 1910 "/tmp/client_pkcs7_signeddata"); 1911 } else { 1912 print_buffer_bin(*signed_data, *signed_data_len, 1913 "/tmp/kdc_pkcs7_signeddata"); 1914 } 1915 #endif 1916 1917 cleanup2: 1918 if (p7si) { 1919 if (alg != NULL) 1920 X509_ALGOR_free(alg); 1921 } 1922 cleanup: 1923 if (p7 != NULL) 1924 PKCS7_free(p7); 1925 free(sig); 1926 1927 return retval; 1928 } 1929 1930 krb5_error_code 1931 cms_signeddata_verify(krb5_context context, 1932 pkinit_plg_crypto_context plgctx, 1933 pkinit_req_crypto_context reqctx, 1934 pkinit_identity_crypto_context idctx, 1935 int cms_msg_type, 1936 int require_crl_checking, 1937 unsigned char *signed_data, 1938 unsigned int signed_data_len, 1939 unsigned char **data, 1940 unsigned int *data_len, 1941 unsigned char **authz_data, 1942 unsigned int *authz_data_len, 1943 int *is_signed) 1944 { 1945 /* 1946 * Warning: Since most openssl functions do not set retval, large chunks of 1947 * this function assume that retval is always a failure and may go to 1948 * cleanup without setting retval explicitly. Make sure retval is not set 1949 * to 0 or errors such as signature verification failure may be converted 1950 * to success with significant security consequences. 1951 */ 1952 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 1953 CMS_ContentInfo *cms = NULL; 1954 BIO *out = NULL; 1955 int flags = CMS_NO_SIGNER_CERT_VERIFY; 1956 int valid_oid = 0; 1957 unsigned int i = 0; 1958 unsigned int vflags = 0, size = 0; 1959 const unsigned char *p = signed_data; 1960 STACK_OF(CMS_SignerInfo) *si_sk = NULL; 1961 CMS_SignerInfo *si = NULL; 1962 X509 *x = NULL; 1963 X509_STORE *store = NULL; 1964 X509_STORE_CTX *cert_ctx; 1965 STACK_OF(X509) *signerCerts = NULL; 1966 STACK_OF(X509) *intermediateCAs = NULL; 1967 STACK_OF(X509_CRL) *signerRevoked = NULL; 1968 STACK_OF(X509_CRL) *revoked = NULL; 1969 STACK_OF(X509) *verified_chain = NULL; 1970 ASN1_OBJECT *oid = NULL; 1971 const ASN1_OBJECT *type = NULL, *etype = NULL; 1972 ASN1_OCTET_STRING **octets; 1973 krb5_external_principal_identifier **krb5_verified_chain = NULL; 1974 krb5_data *authz = NULL; 1975 char buf[DN_BUF_LEN]; 1976 1977 #ifdef DEBUG_ASN1 1978 print_buffer_bin(signed_data, signed_data_len, 1979 "/tmp/client_received_pkcs7_signeddata"); 1980 #endif 1981 if (is_signed) 1982 *is_signed = 1; 1983 1984 oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type); 1985 if (oid == NULL) 1986 goto cleanup; 1987 1988 /* decode received CMS message */ 1989 if ((cms = d2i_CMS_ContentInfo(NULL, &p, (int)signed_data_len)) == NULL) { 1990 retval = oerr(context, 0, _("Failed to decode CMS message")); 1991 goto cleanup; 1992 } 1993 etype = CMS_get0_eContentType(cms); 1994 1995 /* 1996 * Prior to 1.10 the MIT client incorrectly emitted the pkinit structure 1997 * directly in a CMS ContentInfo rather than using SignedData with no 1998 * signers. Handle that case. 1999 */ 2000 type = CMS_get0_type(cms); 2001 if (is_signed && !OBJ_cmp(type, oid)) { 2002 unsigned char *d; 2003 *is_signed = 0; 2004 octets = CMS_get0_content(cms); 2005 if (!octets || ((*octets)->type != V_ASN1_OCTET_STRING)) { 2006 retval = KRB5KDC_ERR_PREAUTH_FAILED; 2007 krb5_set_error_message(context, retval, 2008 _("Invalid pkinit packet: octet string " 2009 "expected")); 2010 goto cleanup; 2011 } 2012 *data_len = ASN1_STRING_length(*octets); 2013 d = malloc(*data_len); 2014 if (d == NULL) { 2015 retval = ENOMEM; 2016 goto cleanup; 2017 } 2018 memcpy(d, ASN1_STRING_get0_data(*octets), *data_len); 2019 *data = d; 2020 goto out; 2021 } else { 2022 /* Verify that the received message is CMS SignedData message. */ 2023 if (OBJ_obj2nid(type) != NID_pkcs7_signed) { 2024 pkiDebug("Expected id-signedData CMS msg (received type = %d)\n", 2025 OBJ_obj2nid(type)); 2026 krb5_set_error_message(context, retval, _("wrong oid\n")); 2027 goto cleanup; 2028 } 2029 } 2030 2031 /* setup to verify X509 certificate used to sign CMS message */ 2032 if (!(store = X509_STORE_new())) 2033 goto cleanup; 2034 2035 /* check if we are inforcing CRL checking */ 2036 vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; 2037 if (require_crl_checking) 2038 X509_STORE_set_verify_cb(store, openssl_callback); 2039 else 2040 X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls); 2041 X509_STORE_set_flags(store, vflags); 2042 2043 /* 2044 * Get the signer's information from the CMS message. Match signer ID 2045 * against anchors and intermediate CAs in case no certs are present in the 2046 * SignedData. If we start sending kdcPkId values in requests, we'll need 2047 * to match against the source of that information too. 2048 */ 2049 CMS_set1_signers_certs(cms, NULL, 0); 2050 CMS_set1_signers_certs(cms, idctx->trustedCAs, CMS_NOINTERN); 2051 CMS_set1_signers_certs(cms, idctx->intermediateCAs, CMS_NOINTERN); 2052 if (((si_sk = CMS_get0_SignerInfos(cms)) == NULL) || 2053 ((si = sk_CMS_SignerInfo_value(si_sk, 0)) == NULL)) { 2054 /* Not actually signed; anonymous case */ 2055 if (!is_signed) 2056 goto cleanup; 2057 *is_signed = 0; 2058 /* We cannot use CMS_dataInit because there may be no digest */ 2059 octets = CMS_get0_content(cms); 2060 if (octets) 2061 out = BIO_new_mem_buf((*octets)->data, (*octets)->length); 2062 if (out == NULL) 2063 goto cleanup; 2064 } else { 2065 CMS_SignerInfo_get0_algs(si, NULL, &x, NULL, NULL); 2066 if (x == NULL) 2067 goto cleanup; 2068 2069 /* create available CRL information (get local CRLs and include CRLs 2070 * received in the CMS message 2071 */ 2072 signerRevoked = CMS_get1_crls(cms); 2073 if (idctx->revoked == NULL) 2074 revoked = signerRevoked; 2075 else if (signerRevoked == NULL) 2076 revoked = idctx->revoked; 2077 else { 2078 size = sk_X509_CRL_num(idctx->revoked); 2079 revoked = sk_X509_CRL_new_null(); 2080 for (i = 0; i < size; i++) 2081 sk_X509_CRL_push(revoked, sk_X509_CRL_value(idctx->revoked, i)); 2082 size = sk_X509_CRL_num(signerRevoked); 2083 for (i = 0; i < size; i++) 2084 sk_X509_CRL_push(revoked, sk_X509_CRL_value(signerRevoked, i)); 2085 } 2086 2087 /* create available intermediate CAs chains (get local intermediateCAs and 2088 * include the CA chain received in the CMS message 2089 */ 2090 signerCerts = CMS_get1_certs(cms); 2091 if (idctx->intermediateCAs == NULL) 2092 intermediateCAs = signerCerts; 2093 else if (signerCerts == NULL) 2094 intermediateCAs = idctx->intermediateCAs; 2095 else { 2096 size = sk_X509_num(idctx->intermediateCAs); 2097 intermediateCAs = sk_X509_new_null(); 2098 for (i = 0; i < size; i++) { 2099 sk_X509_push(intermediateCAs, 2100 sk_X509_value(idctx->intermediateCAs, i)); 2101 } 2102 size = sk_X509_num(signerCerts); 2103 for (i = 0; i < size; i++) { 2104 sk_X509_push(intermediateCAs, sk_X509_value(signerCerts, i)); 2105 } 2106 } 2107 2108 /* initialize x509 context with the received certificate and 2109 * trusted and intermediate CA chains and CRLs 2110 */ 2111 cert_ctx = X509_STORE_CTX_new(); 2112 if (cert_ctx == NULL) 2113 goto cleanup; 2114 if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs)) 2115 goto cleanup; 2116 2117 X509_STORE_CTX_set0_crls(cert_ctx, revoked); 2118 2119 /* add trusted CAs certificates for cert verification */ 2120 if (idctx->trustedCAs != NULL) 2121 X509_STORE_CTX_trusted_stack(cert_ctx, idctx->trustedCAs); 2122 else { 2123 pkiDebug("unable to find any trusted CAs\n"); 2124 goto cleanup; 2125 } 2126 #ifdef DEBUG_CERTCHAIN 2127 if (intermediateCAs != NULL) { 2128 size = sk_X509_num(intermediateCAs); 2129 pkiDebug("untrusted cert chain of size %d\n", size); 2130 for (i = 0; i < size; i++) { 2131 X509_NAME_oneline(X509_get_subject_name( 2132 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf)); 2133 pkiDebug("cert #%d: %s\n", i, buf); 2134 } 2135 } 2136 if (idctx->trustedCAs != NULL) { 2137 size = sk_X509_num(idctx->trustedCAs); 2138 pkiDebug("trusted cert chain of size %d\n", size); 2139 for (i = 0; i < size; i++) { 2140 X509_NAME_oneline(X509_get_subject_name( 2141 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf)); 2142 pkiDebug("cert #%d: %s\n", i, buf); 2143 } 2144 } 2145 if (revoked != NULL) { 2146 size = sk_X509_CRL_num(revoked); 2147 pkiDebug("CRL chain of size %d\n", size); 2148 for (i = 0; i < size; i++) { 2149 X509_CRL *crl = sk_X509_CRL_value(revoked, i); 2150 X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf)); 2151 pkiDebug("crls by CA #%d: %s\n", i , buf); 2152 } 2153 } 2154 #endif 2155 2156 i = X509_verify_cert(cert_ctx); 2157 if (i <= 0) { 2158 int j = X509_STORE_CTX_get_error(cert_ctx); 2159 X509 *cert; 2160 2161 cert = X509_STORE_CTX_get_current_cert(cert_ctx); 2162 reqctx->received_cert = X509_dup(cert); 2163 switch(j) { 2164 case X509_V_ERR_CERT_REVOKED: 2165 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE; 2166 break; 2167 case X509_V_ERR_UNABLE_TO_GET_CRL: 2168 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN; 2169 break; 2170 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 2171 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 2172 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE; 2173 break; 2174 default: 2175 retval = KRB5KDC_ERR_INVALID_CERTIFICATE; 2176 } 2177 (void)oerr_cert(context, retval, cert_ctx, 2178 _("Failed to verify received certificate")); 2179 if (reqctx->received_cert == NULL) 2180 strlcpy(buf, "(none)", sizeof(buf)); 2181 else 2182 X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert), 2183 buf, sizeof(buf)); 2184 pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j, 2185 X509_verify_cert_error_string(j)); 2186 #ifdef DEBUG_CERTCHAIN 2187 size = sk_X509_num(signerCerts); 2188 pkiDebug("received cert chain of size %d\n", size); 2189 for (j = 0; j < size; j++) { 2190 X509 *tmp_cert = sk_X509_value(signerCerts, j); 2191 X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf)); 2192 pkiDebug("cert #%d: %s\n", j, buf); 2193 } 2194 #endif 2195 } else { 2196 /* retrieve verified certificate chain */ 2197 if (cms_msg_type == CMS_SIGN_CLIENT) 2198 verified_chain = X509_STORE_CTX_get1_chain(cert_ctx); 2199 } 2200 X509_STORE_CTX_free(cert_ctx); 2201 if (i <= 0) 2202 goto cleanup; 2203 out = BIO_new(BIO_s_mem()); 2204 if (CMS_verify(cms, NULL, store, NULL, out, flags) == 0) { 2205 if (ERR_peek_last_error() == CMS_R_VERIFICATION_FAILURE) 2206 retval = KRB5KDC_ERR_INVALID_SIG; 2207 else 2208 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED; 2209 (void)oerr(context, retval, _("Failed to verify CMS message")); 2210 goto cleanup; 2211 } 2212 } /* message was signed */ 2213 if (!OBJ_cmp(etype, oid)) 2214 valid_oid = 1; 2215 2216 if (valid_oid) 2217 pkiDebug("CMS Verification successful\n"); 2218 else { 2219 pkiDebug("wrong oid in eContentType\n"); 2220 print_buffer(OBJ_get0_data(etype), OBJ_length(etype)); 2221 retval = KRB5KDC_ERR_PREAUTH_FAILED; 2222 krb5_set_error_message(context, retval, "wrong oid\n"); 2223 goto cleanup; 2224 } 2225 2226 /* transfer the data from CMS message into return buffer */ 2227 for (size = 0;;) { 2228 int remain; 2229 retval = ENOMEM; 2230 if ((*data = realloc(*data, size + 1024 * 10)) == NULL) 2231 goto cleanup; 2232 remain = BIO_read(out, &((*data)[size]), 1024 * 10); 2233 if (remain <= 0) 2234 break; 2235 else 2236 size += remain; 2237 } 2238 *data_len = size; 2239 2240 if (x) { 2241 reqctx->received_cert = X509_dup(x); 2242 2243 /* generate authorization data */ 2244 if (cms_msg_type == CMS_SIGN_CLIENT) { 2245 2246 if (authz_data == NULL || authz_data_len == NULL) 2247 goto out; 2248 2249 *authz_data = NULL; 2250 retval = create_identifiers_from_stack(verified_chain, 2251 &krb5_verified_chain); 2252 if (retval) { 2253 pkiDebug("create_identifiers_from_stack failed\n"); 2254 goto cleanup; 2255 } 2256 2257 retval = k5int_encode_krb5_td_trusted_certifiers((krb5_external_principal_identifier *const *)krb5_verified_chain, &authz); 2258 if (retval) { 2259 pkiDebug("encode_krb5_td_trusted_certifiers failed\n"); 2260 goto cleanup; 2261 } 2262 #ifdef DEBUG_ASN1 2263 print_buffer_bin((unsigned char *)authz->data, authz->length, 2264 "/tmp/kdc_ad_initial_verified_cas"); 2265 #endif 2266 *authz_data = malloc(authz->length); 2267 if (*authz_data == NULL) { 2268 retval = ENOMEM; 2269 goto cleanup; 2270 } 2271 memcpy(*authz_data, authz->data, authz->length); 2272 *authz_data_len = authz->length; 2273 } 2274 } 2275 out: 2276 retval = 0; 2277 2278 cleanup: 2279 if (out != NULL) 2280 BIO_free(out); 2281 if (store != NULL) 2282 X509_STORE_free(store); 2283 if (cms != NULL) { 2284 if (signerCerts != NULL) 2285 sk_X509_pop_free(signerCerts, X509_free); 2286 if (idctx->intermediateCAs != NULL && signerCerts) 2287 sk_X509_free(intermediateCAs); 2288 if (signerRevoked != NULL) 2289 sk_X509_CRL_pop_free(signerRevoked, X509_CRL_free); 2290 if (idctx->revoked != NULL && signerRevoked) 2291 sk_X509_CRL_free(revoked); 2292 CMS_ContentInfo_free(cms); 2293 } 2294 if (verified_chain != NULL) 2295 sk_X509_pop_free(verified_chain, X509_free); 2296 if (krb5_verified_chain != NULL) 2297 free_krb5_external_principal_identifier(&krb5_verified_chain); 2298 if (authz != NULL) 2299 krb5_free_data(context, authz); 2300 2301 return retval; 2302 } 2303 2304 static krb5_error_code 2305 crypto_retrieve_X509_sans(krb5_context context, 2306 pkinit_plg_crypto_context plgctx, 2307 pkinit_req_crypto_context reqctx, 2308 X509 *cert, 2309 krb5_principal **princs_ret, char ***upn_ret, 2310 unsigned char ***dns_ret) 2311 { 2312 krb5_error_code retval = EINVAL; 2313 char buf[DN_BUF_LEN]; 2314 size_t num_sans = 0, p = 0, u = 0, d = 0, i; 2315 int l; 2316 krb5_principal *princs = NULL; 2317 char **upns = NULL; 2318 unsigned char **dnss = NULL; 2319 X509_EXTENSION *ext = NULL; 2320 GENERAL_NAMES *ialt = NULL; 2321 GENERAL_NAME *gen = NULL; 2322 2323 if (princs_ret != NULL) 2324 *princs_ret = NULL; 2325 if (upn_ret != NULL) 2326 *upn_ret = NULL; 2327 if (dns_ret != NULL) 2328 *dns_ret = NULL; 2329 2330 if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) { 2331 pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__); 2332 return retval; 2333 } 2334 2335 if (cert == NULL) { 2336 pkiDebug("%s: no certificate!\n", __FUNCTION__); 2337 return retval; 2338 } 2339 2340 X509_NAME_oneline(X509_get_subject_name(cert), 2341 buf, sizeof(buf)); 2342 2343 l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); 2344 if (l < 0) 2345 return 0; 2346 2347 if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { 2348 TRACE_PKINIT_SAN_CERT_NONE(context, buf); 2349 goto cleanup; 2350 } 2351 num_sans = sk_GENERAL_NAME_num(ialt); 2352 2353 /* OK, we're likely returning something. Allocate return values */ 2354 if (princs_ret != NULL) { 2355 princs = calloc(num_sans + 1, sizeof(krb5_principal)); 2356 if (princs == NULL) { 2357 retval = ENOMEM; 2358 goto cleanup; 2359 } 2360 } 2361 if (upn_ret != NULL) { 2362 upns = calloc(num_sans + 1, sizeof(*upns)); 2363 if (upns == NULL) { 2364 retval = ENOMEM; 2365 goto cleanup; 2366 } 2367 } 2368 if (dns_ret != NULL) { 2369 dnss = calloc(num_sans + 1, sizeof(*dnss)); 2370 if (dnss == NULL) { 2371 retval = ENOMEM; 2372 goto cleanup; 2373 } 2374 } 2375 2376 for (i = 0; i < num_sans; i++) { 2377 krb5_data name = { 0, 0, NULL }; 2378 2379 gen = sk_GENERAL_NAME_value(ialt, i); 2380 switch (gen->type) { 2381 case GEN_OTHERNAME: 2382 name.length = gen->d.otherName->value->value.sequence->length; 2383 name.data = (char *)gen->d.otherName->value->value.sequence->data; 2384 if (princs != NULL && 2385 OBJ_cmp(plgctx->id_pkinit_san, 2386 gen->d.otherName->type_id) == 0) { 2387 #ifdef DEBUG_ASN1 2388 print_buffer_bin((unsigned char *)name.data, name.length, 2389 "/tmp/pkinit_san"); 2390 #endif 2391 if (k5int_decode_krb5_principal_name(&name, &princs[p]) != 0) { 2392 pkiDebug("%s: failed decoding pkinit san value\n", 2393 __FUNCTION__); 2394 } else { 2395 p++; 2396 } 2397 } else if (upns != NULL && 2398 OBJ_cmp(plgctx->id_ms_san_upn, 2399 gen->d.otherName->type_id) == 0) { 2400 /* Prevent abuse of embedded null characters. */ 2401 if (memchr(name.data, '\0', name.length)) 2402 break; 2403 upns[u] = k5memdup0(name.data, name.length, &retval); 2404 if (upns[u] == NULL) 2405 goto cleanup; 2406 u++; 2407 } else { 2408 pkiDebug("%s: unrecognized othername oid in SAN\n", 2409 __FUNCTION__); 2410 continue; 2411 } 2412 2413 break; 2414 case GEN_DNS: 2415 if (dnss != NULL) { 2416 /* Prevent abuse of embedded null characters. */ 2417 if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length)) 2418 break; 2419 pkiDebug("%s: found dns name = %s\n", __FUNCTION__, 2420 gen->d.dNSName->data); 2421 dnss[d] = (unsigned char *) 2422 strdup((char *)gen->d.dNSName->data); 2423 if (dnss[d] == NULL) { 2424 pkiDebug("%s: failed to duplicate dns name\n", 2425 __FUNCTION__); 2426 } else { 2427 d++; 2428 } 2429 } 2430 break; 2431 default: 2432 pkiDebug("%s: SAN type = %d expecting %d\n", __FUNCTION__, 2433 gen->type, GEN_OTHERNAME); 2434 } 2435 } 2436 sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); 2437 2438 TRACE_PKINIT_SAN_CERT_COUNT(context, (int)num_sans, p, u, d, buf); 2439 2440 retval = 0; 2441 if (princs != NULL && *princs != NULL) { 2442 *princs_ret = princs; 2443 princs = NULL; 2444 } 2445 if (upns != NULL && *upns != NULL) { 2446 *upn_ret = upns; 2447 upns = NULL; 2448 } 2449 if (dnss != NULL && *dnss != NULL) { 2450 *dns_ret = dnss; 2451 dnss = NULL; 2452 } 2453 2454 cleanup: 2455 for (i = 0; princs != NULL && princs[i] != NULL; i++) 2456 krb5_free_principal(context, princs[i]); 2457 free(princs); 2458 for (i = 0; upns != NULL && upns[i] != NULL; i++) 2459 free(upns[i]); 2460 free(upns); 2461 for (i = 0; dnss != NULL && dnss[i] != NULL; i++) 2462 free(dnss[i]); 2463 free(dnss); 2464 return retval; 2465 } 2466 2467 krb5_error_code 2468 crypto_retrieve_signer_identity(krb5_context context, 2469 pkinit_identity_crypto_context id_cryptoctx, 2470 const char **identity) 2471 { 2472 *identity = id_cryptoctx->identity; 2473 if (*identity == NULL) 2474 return ENOENT; 2475 return 0; 2476 } 2477 2478 krb5_error_code 2479 crypto_retrieve_cert_sans(krb5_context context, 2480 pkinit_plg_crypto_context plgctx, 2481 pkinit_req_crypto_context reqctx, 2482 pkinit_identity_crypto_context idctx, 2483 krb5_principal **princs_ret, char ***upn_ret, 2484 unsigned char ***dns_ret) 2485 { 2486 krb5_error_code retval = EINVAL; 2487 2488 if (reqctx->received_cert == NULL) { 2489 pkiDebug("%s: No certificate!\n", __FUNCTION__); 2490 return retval; 2491 } 2492 2493 return crypto_retrieve_X509_sans(context, plgctx, reqctx, 2494 reqctx->received_cert, princs_ret, 2495 upn_ret, dns_ret); 2496 } 2497 2498 krb5_error_code 2499 crypto_check_cert_eku(krb5_context context, 2500 pkinit_plg_crypto_context plgctx, 2501 pkinit_req_crypto_context reqctx, 2502 pkinit_identity_crypto_context idctx, 2503 int checking_kdc_cert, 2504 int allow_secondary_usage, 2505 int *valid_eku) 2506 { 2507 char buf[DN_BUF_LEN]; 2508 int found_eku = 0; 2509 krb5_error_code retval = EINVAL; 2510 int i; 2511 2512 *valid_eku = 0; 2513 if (reqctx->received_cert == NULL) 2514 goto cleanup; 2515 2516 X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert), 2517 buf, sizeof(buf)); 2518 2519 if ((i = X509_get_ext_by_NID(reqctx->received_cert, 2520 NID_ext_key_usage, -1)) >= 0) { 2521 EXTENDED_KEY_USAGE *extusage; 2522 2523 extusage = X509_get_ext_d2i(reqctx->received_cert, NID_ext_key_usage, 2524 NULL, NULL); 2525 if (extusage) { 2526 pkiDebug("%s: found eku info in the cert\n", __FUNCTION__); 2527 for (i = 0; found_eku == 0 && i < sk_ASN1_OBJECT_num(extusage); i++) { 2528 ASN1_OBJECT *tmp_oid; 2529 2530 tmp_oid = sk_ASN1_OBJECT_value(extusage, i); 2531 pkiDebug("%s: checking eku %d of %d, allow_secondary = %d\n", 2532 __FUNCTION__, i+1, sk_ASN1_OBJECT_num(extusage), 2533 allow_secondary_usage); 2534 if (checking_kdc_cert) { 2535 if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPKdc) == 0) 2536 || (allow_secondary_usage 2537 && OBJ_cmp(tmp_oid, plgctx->id_kp_serverAuth) == 0)) 2538 found_eku = 1; 2539 } else { 2540 if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPClientAuth) == 0) 2541 || (allow_secondary_usage 2542 && OBJ_cmp(tmp_oid, plgctx->id_ms_kp_sc_logon) == 0)) 2543 found_eku = 1; 2544 } 2545 } 2546 } 2547 EXTENDED_KEY_USAGE_free(extusage); 2548 2549 if (found_eku) { 2550 ASN1_BIT_STRING *usage = NULL; 2551 2552 /* check that digitalSignature KeyUsage is present */ 2553 X509_check_ca(reqctx->received_cert); 2554 if ((usage = X509_get_ext_d2i(reqctx->received_cert, 2555 NID_key_usage, NULL, NULL))) { 2556 2557 if (!ku_reject(reqctx->received_cert, 2558 X509v3_KU_DIGITAL_SIGNATURE)) { 2559 TRACE_PKINIT_EKU(context); 2560 *valid_eku = 1; 2561 } else 2562 TRACE_PKINIT_EKU_NO_KU(context); 2563 } 2564 ASN1_BIT_STRING_free(usage); 2565 } 2566 } 2567 retval = 0; 2568 cleanup: 2569 pkiDebug("%s: returning retval %d, valid_eku %d\n", 2570 __FUNCTION__, retval, *valid_eku); 2571 return retval; 2572 } 2573 2574 static krb5_error_code 2575 octetstring2key(krb5_context context, krb5_enctype etype, 2576 const krb5_data *secret, krb5_keyblock *key_block) 2577 { 2578 krb5_error_code retval; 2579 unsigned char *buf = NULL; 2580 unsigned char md[SHA_DIGEST_LENGTH]; 2581 unsigned char counter; 2582 size_t keybytes, keylength, offset; 2583 krb5_data random_data; 2584 EVP_MD_CTX *sha1_ctx = NULL; 2585 2586 buf = k5alloc(secret->length, &retval); 2587 if (buf == NULL) 2588 goto cleanup; 2589 2590 sha1_ctx = EVP_MD_CTX_new(); 2591 if (sha1_ctx == NULL) { 2592 retval = KRB5_CRYPTO_INTERNAL; 2593 goto cleanup; 2594 } 2595 2596 counter = 0; 2597 offset = 0; 2598 do { 2599 if (!EVP_DigestInit(sha1_ctx, EVP_sha1()) || 2600 !EVP_DigestUpdate(sha1_ctx, &counter, 1) || 2601 !EVP_DigestUpdate(sha1_ctx, secret->data, secret->length) || 2602 !EVP_DigestFinal(sha1_ctx, md, NULL)) { 2603 retval = KRB5_CRYPTO_INTERNAL; 2604 goto cleanup; 2605 } 2606 2607 if (secret->length - offset < sizeof(md)) 2608 memcpy(buf + offset, md, secret->length - offset); 2609 else 2610 memcpy(buf + offset, md, sizeof(md)); 2611 2612 offset += sizeof(md); 2613 counter++; 2614 } while (offset < secret->length); 2615 2616 key_block->magic = 0; 2617 key_block->enctype = etype; 2618 2619 retval = krb5_c_keylengths(context, etype, &keybytes, &keylength); 2620 if (retval) 2621 goto cleanup; 2622 2623 key_block->length = keylength; 2624 key_block->contents = k5alloc(keylength, &retval); 2625 if (key_block->contents == NULL) 2626 goto cleanup; 2627 2628 random_data.length = keybytes; 2629 random_data.data = (char *)buf; 2630 2631 retval = krb5_c_random_to_key(context, etype, &random_data, key_block); 2632 if (retval) 2633 goto cleanup; 2634 2635 TRACE_PKINIT_KDF_OS2K(context, key_block); 2636 2637 cleanup: 2638 EVP_MD_CTX_free(sha1_ctx); 2639 free(buf); 2640 /* If this is an error return, free the allocated keyblock, if any */ 2641 if (retval) { 2642 krb5_free_keyblock_contents(context, key_block); 2643 } 2644 2645 return retval; 2646 } 2647 2648 2649 /* Return the OpenSSL descriptor for the given RFC 5652 OID specified in RFC 2650 * 8636. RFC 8636 defines a SHA384 variant, but we don't use it. */ 2651 static const EVP_MD * 2652 algid_to_md(const krb5_data *alg_id) 2653 { 2654 if (data_eq(*alg_id, kdf_sha1_id)) 2655 return EVP_sha1(); 2656 if (data_eq(*alg_id, kdf_sha256_id)) 2657 return EVP_sha256(); 2658 if (data_eq(*alg_id, kdf_sha512_id)) 2659 return EVP_sha512(); 2660 return NULL; 2661 } 2662 2663 #if OPENSSL_VERSION_NUMBER >= 0x30000000L 2664 2665 #define sskdf openssl_sskdf 2666 static krb5_error_code 2667 openssl_sskdf(krb5_context context, const EVP_MD *md, const krb5_data *secret, 2668 const krb5_data *info, size_t len, krb5_data *out) 2669 { 2670 krb5_error_code ret; 2671 EVP_KDF *kdf = NULL; 2672 EVP_KDF_CTX *kctx = NULL; 2673 OSSL_PARAM params[4], *p = params; 2674 2675 ret = alloc_data(out, len); 2676 if (ret) 2677 goto cleanup; 2678 2679 kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); 2680 if (kdf == NULL) { 2681 ret = oerr(context, KRB5_CRYPTO_INTERNAL, _("Failed to fetch SSKDF")); 2682 goto cleanup; 2683 } 2684 2685 kctx = EVP_KDF_CTX_new(kdf); 2686 if (!kctx) { 2687 ret = oerr(context, KRB5_CRYPTO_INTERNAL, 2688 _("Failed to instantiate SSKDF")); 2689 goto cleanup; 2690 } 2691 2692 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, 2693 (char *)EVP_MD_get0_name(md), 0); 2694 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, 2695 secret->data, secret->length); 2696 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, 2697 info->data, info->length); 2698 *p = OSSL_PARAM_construct_end(); 2699 if (EVP_KDF_derive(kctx, (uint8_t *)out->data, len, params) <= 0) { 2700 ret = oerr(context, KRB5_CRYPTO_INTERNAL, 2701 _("Failed to derive key using SSKDF")); 2702 goto cleanup; 2703 } 2704 2705 ret = 0; 2706 2707 cleanup: 2708 EVP_KDF_free(kdf); 2709 EVP_KDF_CTX_free(kctx); 2710 return ret; 2711 } 2712 2713 #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 2714 2715 #define sskdf builtin_sskdf 2716 static krb5_error_code 2717 builtin_sskdf(krb5_context context, const EVP_MD *md, const krb5_data *secret, 2718 const krb5_data *info, size_t len, krb5_data *out) 2719 { 2720 krb5_error_code ret; 2721 uint32_t counter = 1, reps; 2722 uint8_t be_counter[4], *outptr; 2723 EVP_MD_CTX *ctx = NULL; 2724 unsigned int s, hash_len; 2725 2726 hash_len = EVP_MD_size(md); 2727 2728 /* 1. reps = keydatalen (K) / hash length (H) rounded up. */ 2729 reps = (len + hash_len - 1) / hash_len; 2730 2731 /* Allocate enough space in the random data buffer to hash directly into 2732 * it, even if the last hash will make it bigger than the key length. */ 2733 ret = alloc_data(out, reps * hash_len); 2734 if (ret) 2735 goto cleanup; 2736 out->length = len; 2737 2738 /* 2739 * 2. Initialize a 32-bit, big-endian bit string counter as 1. 2740 * 3. For i = 1 to reps by 1, do the following: 2741 * - Compute Hashi = H(counter || Z || OtherInfo). 2742 * - Increment counter (modulo 2^32) 2743 * 4. Set key = Hash1 || Hash2 || ... so that length of key is K 2744 * bytes. 2745 */ 2746 outptr = (uint8_t *)out->data; 2747 for (counter = 1; counter <= reps; counter++) { 2748 store_32_be(counter, be_counter); 2749 2750 ctx = EVP_MD_CTX_new(); 2751 if (ctx == NULL) { 2752 ret = KRB5_CRYPTO_INTERNAL; 2753 goto cleanup; 2754 } 2755 2756 /* - Compute Hashi = H(counter || Z || OtherInfo). */ 2757 if (!EVP_DigestInit(ctx, md) || 2758 !EVP_DigestUpdate(ctx, be_counter, 4) || 2759 !EVP_DigestUpdate(ctx, secret->data, secret->length) || 2760 !EVP_DigestUpdate(ctx, info->data, info->length) || 2761 !EVP_DigestFinal(ctx, outptr, &s)) { 2762 ret = oerr(context, KRB5_CRYPTO_INTERNAL, 2763 _("Failed to compute digest")); 2764 goto cleanup; 2765 } 2766 2767 assert(s == hash_len); 2768 outptr += s; 2769 2770 EVP_MD_CTX_free(ctx); 2771 ctx = NULL; 2772 } 2773 2774 cleanup: 2775 EVP_MD_CTX_free(ctx); 2776 return ret; 2777 } 2778 2779 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ 2780 2781 /* id-pkinit-kdf family, as specified by RFC 8636. If alg_oid is null, 2782 * octet2string(), as specified by RFC 4556. */ 2783 krb5_error_code 2784 pkinit_kdf(krb5_context context, krb5_data *secret, const krb5_data *alg_oid, 2785 krb5_const_principal party_u_info, 2786 krb5_const_principal party_v_info, krb5_enctype enctype, 2787 const krb5_data *as_req, const krb5_data *pk_as_rep, 2788 krb5_keyblock *key_block) 2789 { 2790 krb5_error_code ret; 2791 size_t rand_len = 0, key_len = 0; 2792 const EVP_MD *md; 2793 krb5_sp80056a_other_info other_info_fields; 2794 krb5_pkinit_supp_pub_info supp_pub_info_fields; 2795 krb5_data *other_info = NULL, *supp_pub_info = NULL; 2796 krb5_data random_data = empty_data(); 2797 krb5_algorithm_identifier alg_id; 2798 char *hash_name = NULL; 2799 2800 if (alg_oid == NULL) 2801 return octetstring2key(context, enctype, secret, key_block); 2802 2803 ret = krb5_c_keylengths(context, enctype, &rand_len, &key_len); 2804 if (ret) 2805 goto cleanup; 2806 2807 /* Allocate and initialize the key block. */ 2808 key_block->magic = 0; 2809 key_block->enctype = enctype; 2810 key_block->length = key_len; 2811 key_block->contents = k5calloc(key_block->length, 1, &ret); 2812 if (key_block->contents == NULL) 2813 goto cleanup; 2814 2815 /* If this is anonymous pkinit, use the anonymous principle for 2816 * party_u_info. */ 2817 if (party_u_info && 2818 krb5_principal_compare_any_realm(context, party_u_info, 2819 krb5_anonymous_principal())) { 2820 party_u_info = krb5_anonymous_principal(); 2821 } 2822 2823 md = algid_to_md(alg_oid); 2824 if (md == NULL) { 2825 krb5_set_error_message(context, KRB5_ERR_BAD_S2K_PARAMS, 2826 "Bad algorithm ID passed to PK-INIT KDF."); 2827 return KRB5_ERR_BAD_S2K_PARAMS; 2828 } 2829 2830 /* Encode the ASN.1 octet string for "SuppPubInfo". */ 2831 supp_pub_info_fields.enctype = enctype; 2832 supp_pub_info_fields.as_req = *as_req; 2833 supp_pub_info_fields.pk_as_rep = *pk_as_rep; 2834 ret = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields, 2835 &supp_pub_info); 2836 if (ret) 2837 goto cleanup; 2838 2839 /* Now encode the ASN.1 octet string for "OtherInfo". */ 2840 memset(&alg_id, 0, sizeof(alg_id)); 2841 alg_id.algorithm = *alg_oid; 2842 other_info_fields.algorithm_identifier = alg_id; 2843 other_info_fields.party_u_info = (krb5_principal)party_u_info; 2844 other_info_fields.party_v_info = (krb5_principal)party_v_info; 2845 other_info_fields.supp_pub_info = *supp_pub_info; 2846 ret = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info); 2847 if (ret) 2848 goto cleanup; 2849 2850 ret = sskdf(context, md, secret, other_info, rand_len, &random_data); 2851 if (ret) 2852 goto cleanup; 2853 2854 ret = krb5_c_random_to_key(context, enctype, &random_data, key_block); 2855 if (ret) 2856 goto cleanup; 2857 2858 TRACE_PKINIT_KDF_ALG(context, alg_oid, key_block); 2859 2860 cleanup: 2861 if (ret) 2862 krb5_free_keyblock_contents(context, key_block); 2863 free(hash_name); 2864 zapfree(random_data.data, random_data.length); 2865 krb5_free_data(context, other_info); 2866 krb5_free_data(context, supp_pub_info); 2867 return ret; 2868 } 2869 2870 /* Return the equivalent finite-field bit strength of pkey if it matches a 2871 * well-known group, or -1 if it doesn't. */ 2872 static int 2873 check_dh_wellknown(pkinit_plg_crypto_context cryptoctx, EVP_PKEY *pkey) 2874 { 2875 int nbits = EVP_PKEY_get_bits(pkey); 2876 2877 if (nbits == 1024 && EVP_PKEY_parameters_eq(cryptoctx->dh_1024, pkey) == 1) 2878 return nbits; 2879 if (nbits == 2048 && EVP_PKEY_parameters_eq(cryptoctx->dh_2048, pkey) == 1) 2880 return nbits; 2881 if (nbits == 4096 && EVP_PKEY_parameters_eq(cryptoctx->dh_4096, pkey) == 1) 2882 return nbits; 2883 if (nbits == 256 && EVP_PKEY_parameters_eq(cryptoctx->ec_p256, pkey) == 1) 2884 return PKINIT_DH_P256_BITS; 2885 if (nbits == 384 && EVP_PKEY_parameters_eq(cryptoctx->ec_p384, pkey) == 1) 2886 return PKINIT_DH_P384_BITS; 2887 if (nbits == 521 && EVP_PKEY_parameters_eq(cryptoctx->ec_p521, pkey) == 1) 2888 return PKINIT_DH_P521_BITS; 2889 return -1; 2890 } 2891 2892 /* Return a short description of the Diffie-Hellman group with the given 2893 * finite-field group size equivalent. */ 2894 static const char * 2895 group_desc(int dh_bits) 2896 { 2897 switch (dh_bits) { 2898 case PKINIT_DH_P256_BITS: return "P-256"; 2899 case PKINIT_DH_P384_BITS: return "P-384"; 2900 case PKINIT_DH_P521_BITS: return "P-521"; 2901 case 1024: return "1024-bit DH"; 2902 case 2048: return "2048-bit DH"; 2903 case 4096: return "4096-bit DH"; 2904 } 2905 return "(unknown)"; 2906 } 2907 2908 static EVP_PKEY * 2909 choose_dh_group(pkinit_plg_crypto_context plg_cryptoctx, int dh_size) 2910 { 2911 if (dh_size == 1024) 2912 return plg_cryptoctx->dh_1024; 2913 if (dh_size == 2048) 2914 return plg_cryptoctx->dh_2048; 2915 if (dh_size == 4096) 2916 return plg_cryptoctx->dh_4096; 2917 if (dh_size == PKINIT_DH_P256_BITS) 2918 return plg_cryptoctx->ec_p256; 2919 if (dh_size == PKINIT_DH_P384_BITS) 2920 return plg_cryptoctx->ec_p384; 2921 if (dh_size == PKINIT_DH_P521_BITS) 2922 return plg_cryptoctx->ec_p521; 2923 return NULL; 2924 } 2925 2926 krb5_error_code 2927 client_create_dh(krb5_context context, 2928 pkinit_plg_crypto_context plg_cryptoctx, 2929 pkinit_req_crypto_context cryptoctx, 2930 pkinit_identity_crypto_context id_cryptoctx, 2931 int dh_size, krb5_data *spki_out) 2932 { 2933 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 2934 EVP_PKEY *params = NULL, *pkey = NULL; 2935 2936 *spki_out = empty_data(); 2937 2938 params = choose_dh_group(plg_cryptoctx, dh_size); 2939 if (params == NULL) 2940 goto cleanup; 2941 TRACE_PKINIT_DH_PROPOSING_GROUP(context, group_desc(dh_size)); 2942 2943 pkey = generate_dh_pkey(params); 2944 if (pkey == NULL) 2945 goto cleanup; 2946 2947 retval = encode_spki(pkey, spki_out); 2948 if (retval) 2949 goto cleanup; 2950 2951 EVP_PKEY_free(cryptoctx->client_pkey); 2952 cryptoctx->client_pkey = pkey; 2953 pkey = NULL; 2954 2955 cleanup: 2956 EVP_PKEY_free(pkey); 2957 return retval; 2958 } 2959 2960 krb5_error_code 2961 client_process_dh(krb5_context context, 2962 pkinit_plg_crypto_context plg_cryptoctx, 2963 pkinit_req_crypto_context cryptoctx, 2964 pkinit_identity_crypto_context id_cryptoctx, 2965 unsigned char *subjectPublicKey_data, 2966 unsigned int subjectPublicKey_length, 2967 unsigned char **client_key_out, 2968 unsigned int *client_key_len_out) 2969 { 2970 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 2971 EVP_PKEY *server_pkey = NULL; 2972 uint8_t *client_key = NULL; 2973 unsigned int client_key_len; 2974 2975 *client_key_out = NULL; 2976 *client_key_len_out = 0; 2977 2978 server_pkey = compose_dh_pkey(cryptoctx->client_pkey, 2979 subjectPublicKey_data, 2980 subjectPublicKey_length); 2981 if (server_pkey == NULL) { 2982 retval = KRB5_PREAUTH_FAILED; 2983 k5_setmsg(context, retval, _("Cannot compose PKINIT KDC public key")); 2984 goto cleanup; 2985 } 2986 2987 if (!dh_result(cryptoctx->client_pkey, server_pkey, 2988 &client_key, &client_key_len)) 2989 goto cleanup; 2990 2991 #ifdef DEBUG_DH 2992 print_pubkey(server_pub_key, "server's pub_key="); 2993 pkiDebug("client computed key (%d)= ", client_key_len); 2994 print_buffer(client_key, client_key_len); 2995 #endif 2996 2997 *client_key_out = client_key; 2998 *client_key_len_out = client_key_len; 2999 client_key = NULL; 3000 3001 retval = 0; 3002 3003 cleanup: 3004 EVP_PKEY_free(server_pkey); 3005 free(client_key); 3006 return retval; 3007 } 3008 3009 krb5_error_code 3010 server_check_dh(krb5_context context, 3011 pkinit_plg_crypto_context cryptoctx, 3012 pkinit_req_crypto_context req_cryptoctx, 3013 pkinit_identity_crypto_context id_cryptoctx, 3014 const krb5_data *client_spki, 3015 int minbits) 3016 { 3017 EVP_PKEY *client_pkey = NULL; 3018 int dh_bits; 3019 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; 3020 3021 client_pkey = decode_spki(client_spki); 3022 if (client_pkey == NULL) { 3023 pkiDebug("failed to decode dhparams\n"); 3024 goto cleanup; 3025 } 3026 3027 dh_bits = check_dh_wellknown(cryptoctx, client_pkey); 3028 if (dh_bits == -1 || dh_bits < minbits) { 3029 TRACE_PKINIT_DH_REJECTING_GROUP(context, group_desc(dh_bits), 3030 group_desc(minbits)); 3031 goto cleanup; 3032 } 3033 TRACE_PKINIT_DH_RECEIVED_GROUP(context, group_desc(dh_bits)); 3034 3035 retval = 0; 3036 3037 cleanup: 3038 if (retval == 0) 3039 req_cryptoctx->client_pkey = client_pkey; 3040 else 3041 EVP_PKEY_free(client_pkey); 3042 3043 return retval; 3044 } 3045 3046 /* kdc's dh function */ 3047 krb5_error_code 3048 server_process_dh(krb5_context context, 3049 pkinit_plg_crypto_context plg_cryptoctx, 3050 pkinit_req_crypto_context cryptoctx, 3051 pkinit_identity_crypto_context id_cryptoctx, 3052 unsigned char **dh_pubkey_out, 3053 unsigned int *dh_pubkey_len_out, 3054 unsigned char **server_key_out, 3055 unsigned int *server_key_len_out) 3056 { 3057 krb5_error_code retval = ENOMEM; 3058 EVP_PKEY *server_pkey = NULL; 3059 unsigned char *dh_pubkey = NULL, *server_key = NULL; 3060 unsigned int dh_pubkey_len = 0, server_key_len = 0; 3061 3062 *dh_pubkey_out = *server_key_out = NULL; 3063 *dh_pubkey_len_out = *server_key_len_out = 0; 3064 3065 /* Generate a server DH key with the same parameters as the client key. */ 3066 server_pkey = generate_dh_pkey(cryptoctx->client_pkey); 3067 if (server_pkey == NULL) 3068 goto cleanup; 3069 3070 if (!dh_result(server_pkey, cryptoctx->client_pkey, &server_key, 3071 &server_key_len)) 3072 goto cleanup; 3073 3074 if (!dh_pubkey_der(server_pkey, &dh_pubkey, &dh_pubkey_len)) 3075 goto cleanup; 3076 3077 *dh_pubkey_out = dh_pubkey; 3078 *dh_pubkey_len_out = dh_pubkey_len; 3079 *server_key_out = server_key; 3080 *server_key_len_out = server_key_len; 3081 dh_pubkey = server_key = NULL; 3082 3083 retval = 0; 3084 3085 cleanup: 3086 EVP_PKEY_free(server_pkey); 3087 free(dh_pubkey); 3088 free(server_key); 3089 3090 return retval; 3091 } 3092 3093 int 3094 pkinit_openssl_init(void) 3095 { 3096 /* Initialize OpenSSL. */ 3097 ERR_load_crypto_strings(); 3098 OpenSSL_add_all_algorithms(); 3099 return 0; 3100 } 3101 3102 static krb5_error_code 3103 pkinit_create_sequence_of_principal_identifiers( 3104 krb5_context context, 3105 pkinit_plg_crypto_context plg_cryptoctx, 3106 pkinit_req_crypto_context req_cryptoctx, 3107 pkinit_identity_crypto_context id_cryptoctx, 3108 int type, 3109 krb5_pa_data ***e_data_out) 3110 { 3111 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 3112 krb5_external_principal_identifier **krb5_trusted_certifiers = NULL; 3113 krb5_data *td_certifiers = NULL; 3114 krb5_pa_data **pa_data = NULL; 3115 3116 switch(type) { 3117 case TD_TRUSTED_CERTIFIERS: 3118 retval = create_krb5_trustedCertifiers(context, plg_cryptoctx, 3119 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers); 3120 if (retval) { 3121 pkiDebug("create_krb5_trustedCertifiers failed\n"); 3122 goto cleanup; 3123 } 3124 break; 3125 case TD_INVALID_CERTIFICATES: 3126 retval = create_krb5_invalidCertificates(context, plg_cryptoctx, 3127 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers); 3128 if (retval) { 3129 pkiDebug("create_krb5_invalidCertificates failed\n"); 3130 goto cleanup; 3131 } 3132 break; 3133 default: 3134 retval = -1; 3135 goto cleanup; 3136 } 3137 3138 retval = k5int_encode_krb5_td_trusted_certifiers((krb5_external_principal_identifier *const *)krb5_trusted_certifiers, &td_certifiers); 3139 if (retval) { 3140 pkiDebug("encode_krb5_td_trusted_certifiers failed\n"); 3141 goto cleanup; 3142 } 3143 #ifdef DEBUG_ASN1 3144 print_buffer_bin((unsigned char *)td_certifiers->data, 3145 td_certifiers->length, "/tmp/kdc_td_certifiers"); 3146 #endif 3147 pa_data = malloc(2 * sizeof(krb5_pa_data *)); 3148 if (pa_data == NULL) { 3149 retval = ENOMEM; 3150 goto cleanup; 3151 } 3152 pa_data[1] = NULL; 3153 pa_data[0] = malloc(sizeof(krb5_pa_data)); 3154 if (pa_data[0] == NULL) { 3155 free(pa_data); 3156 retval = ENOMEM; 3157 goto cleanup; 3158 } 3159 pa_data[0]->pa_type = type; 3160 pa_data[0]->length = td_certifiers->length; 3161 pa_data[0]->contents = (krb5_octet *)td_certifiers->data; 3162 *e_data_out = pa_data; 3163 retval = 0; 3164 3165 cleanup: 3166 if (krb5_trusted_certifiers != NULL) 3167 free_krb5_external_principal_identifier(&krb5_trusted_certifiers); 3168 free(td_certifiers); 3169 return retval; 3170 } 3171 3172 krb5_error_code 3173 pkinit_create_td_trusted_certifiers(krb5_context context, 3174 pkinit_plg_crypto_context plg_cryptoctx, 3175 pkinit_req_crypto_context req_cryptoctx, 3176 pkinit_identity_crypto_context id_cryptoctx, 3177 krb5_pa_data ***e_data_out) 3178 { 3179 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 3180 3181 retval = pkinit_create_sequence_of_principal_identifiers(context, 3182 plg_cryptoctx, req_cryptoctx, id_cryptoctx, 3183 TD_TRUSTED_CERTIFIERS, e_data_out); 3184 3185 return retval; 3186 } 3187 3188 krb5_error_code 3189 pkinit_create_td_invalid_certificate( 3190 krb5_context context, 3191 pkinit_plg_crypto_context plg_cryptoctx, 3192 pkinit_req_crypto_context req_cryptoctx, 3193 pkinit_identity_crypto_context id_cryptoctx, 3194 krb5_pa_data ***e_data_out) 3195 { 3196 krb5_error_code retval = KRB5KRB_ERR_GENERIC; 3197 3198 retval = pkinit_create_sequence_of_principal_identifiers(context, 3199 plg_cryptoctx, req_cryptoctx, id_cryptoctx, 3200 TD_INVALID_CERTIFICATES, e_data_out); 3201 3202 return retval; 3203 } 3204 3205 krb5_error_code 3206 pkinit_create_td_dh_parameters(krb5_context context, 3207 pkinit_plg_crypto_context plg_cryptoctx, 3208 pkinit_req_crypto_context req_cryptoctx, 3209 pkinit_identity_crypto_context id_cryptoctx, 3210 pkinit_plg_opts *opts, 3211 krb5_pa_data ***e_data_out) 3212 { 3213 krb5_error_code ret; 3214 int i; 3215 krb5_pa_data **pa_data = NULL; 3216 krb5_data *der_alglist = NULL; 3217 krb5_algorithm_identifier alg_1024 = { dh_oid, oakley_1024 }; 3218 krb5_algorithm_identifier alg_2048 = { dh_oid, oakley_2048 }; 3219 krb5_algorithm_identifier alg_4096 = { dh_oid, oakley_4096 }; 3220 krb5_algorithm_identifier alg_p256 = { ec_oid, ec_p256 }; 3221 krb5_algorithm_identifier alg_p384 = { ec_oid, ec_p384 }; 3222 krb5_algorithm_identifier alg_p521 = { ec_oid, ec_p521 }; 3223 krb5_algorithm_identifier *alglist[7]; 3224 3225 i = 0; 3226 if (plg_cryptoctx->ec_p256 != NULL && 3227 opts->dh_min_bits <= PKINIT_DH_P256_BITS) 3228 alglist[i++] = &alg_p256; 3229 if (plg_cryptoctx->ec_p384 != NULL && 3230 opts->dh_min_bits <= PKINIT_DH_P384_BITS) 3231 alglist[i++] = &alg_p384; 3232 if (plg_cryptoctx->ec_p521 != NULL) 3233 alglist[i++] = &alg_p521; 3234 if (plg_cryptoctx->dh_2048 != NULL && opts->dh_min_bits <= 2048) 3235 alglist[i++] = &alg_2048; 3236 if (plg_cryptoctx->dh_4096 != NULL && opts->dh_min_bits <= 4096) 3237 alglist[i++] = &alg_4096; 3238 if (plg_cryptoctx->dh_1024 != NULL && opts->dh_min_bits <= 1024) 3239 alglist[i++] = &alg_1024; 3240 alglist[i] = NULL; 3241 3242 if (i == 0) { 3243 ret = KRB5KRB_ERR_GENERIC; 3244 k5_setmsg(context, ret, 3245 _("OpenSSL has no supported key exchange groups for " 3246 "pkinit_dh_min_bits=%d"), opts->dh_min_bits); 3247 goto cleanup; 3248 } 3249 3250 ret = k5int_encode_krb5_td_dh_parameters(alglist, &der_alglist); 3251 if (ret) 3252 goto cleanup; 3253 3254 pa_data = k5calloc(2, sizeof(*pa_data), &ret); 3255 if (pa_data == NULL) 3256 goto cleanup; 3257 pa_data[1] = NULL; 3258 pa_data[0] = k5alloc(sizeof(*pa_data[0]), &ret); 3259 if (pa_data[0] == NULL) { 3260 free(pa_data); 3261 goto cleanup; 3262 } 3263 pa_data[0]->pa_type = TD_DH_PARAMETERS; 3264 pa_data[0]->length = der_alglist->length; 3265 pa_data[0]->contents = (krb5_octet *)der_alglist->data; 3266 der_alglist->data = NULL; 3267 *e_data_out = pa_data; 3268 3269 cleanup: 3270 krb5_free_data(context, der_alglist); 3271 return ret; 3272 } 3273 3274 krb5_error_code 3275 pkinit_check_kdc_pkid(krb5_context context, 3276 pkinit_plg_crypto_context plg_cryptoctx, 3277 pkinit_req_crypto_context req_cryptoctx, 3278 pkinit_identity_crypto_context id_cryptoctx, 3279 unsigned char *pdid_buf, 3280 unsigned int pkid_len, 3281 int *valid_kdcPkId) 3282 { 3283 PKCS7_ISSUER_AND_SERIAL *is = NULL; 3284 const unsigned char *p = pdid_buf; 3285 int status = 1; 3286 X509 *kdc_cert = id_cryptoctx->my_cert; 3287 3288 *valid_kdcPkId = 0; 3289 pkiDebug("found kdcPkId in AS REQ\n"); 3290 is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, (int)pkid_len); 3291 if (is == NULL) 3292 return KRB5KDC_ERR_PREAUTH_FAILED; 3293 3294 status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer); 3295 if (!status) { 3296 status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial); 3297 if (!status) 3298 *valid_kdcPkId = 1; 3299 } 3300 3301 X509_NAME_free(is->issuer); 3302 ASN1_INTEGER_free(is->serial); 3303 free(is); 3304 3305 return 0; 3306 } 3307 3308 krb5_error_code 3309 pkinit_process_td_dh_params(krb5_context context, 3310 pkinit_plg_crypto_context cryptoctx, 3311 pkinit_req_crypto_context req_cryptoctx, 3312 pkinit_identity_crypto_context id_cryptoctx, 3313 krb5_algorithm_identifier **algId, 3314 int *new_dh_size) 3315 { 3316 krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; 3317 EVP_PKEY *params = NULL; 3318 size_t i; 3319 int dh_bits, old_dh_size; 3320 3321 pkiDebug("dh parameters\n"); 3322 3323 old_dh_size = *new_dh_size; 3324 3325 for (i = 0; algId[i] != NULL; i++) { 3326 /* Free any parameters from the previous iteration. */ 3327 EVP_PKEY_free(params); 3328 params = NULL; 3329 3330 if (data_eq(algId[i]->algorithm, dh_oid)) 3331 params = decode_dh_params(&algId[i]->parameters); 3332 else if (data_eq(algId[i]->algorithm, ec_oid)) 3333 params = decode_ec_params(&algId[i]->parameters); 3334 if (params == NULL) 3335 continue; 3336 3337 dh_bits = check_dh_wellknown(cryptoctx, params); 3338 /* Skip any parameters shorter than the previous size or unknown. */ 3339 if (dh_bits == -1 || dh_bits < old_dh_size) 3340 continue; 3341 TRACE_PKINIT_DH_NEGOTIATED_GROUP(context, group_desc(dh_bits)); 3342 3343 *new_dh_size = dh_bits; 3344 retval = 0; 3345 goto cleanup; 3346 } 3347 3348 cleanup: 3349 EVP_PKEY_free(params); 3350 return retval; 3351 } 3352 3353 static int 3354 openssl_callback(int ok, X509_STORE_CTX * ctx) 3355 { 3356 #ifdef DEBUG 3357 if (!ok) { 3358 X509 *cert = X509_STORE_CTX_get_current_cert(ctx); 3359 int err = X509_STORE_CTX_get_error(ctx); 3360 const char *errmsg = X509_verify_cert_error_string(err); 3361 char buf[DN_BUF_LEN]; 3362 3363 X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); 3364 pkiDebug("cert = %s\n", buf); 3365 pkiDebug("callback function: %d (%s)\n", err, errmsg); 3366 } 3367 #endif 3368 return ok; 3369 } 3370 3371 static int 3372 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx) 3373 { 3374 if (ok) 3375 return ok; 3376 return X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL; 3377 } 3378 3379 static ASN1_OBJECT * 3380 pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type) 3381 { 3382 switch (pkcs7_type) { 3383 case CMS_SIGN_CLIENT: 3384 return cryptoctx->id_pkinit_authData; 3385 case CMS_SIGN_SERVER: 3386 return cryptoctx->id_pkinit_DHKeyData; 3387 case CMS_ENVEL_SERVER: 3388 return cryptoctx->id_pkinit_rkeyData; 3389 default: 3390 return NULL; 3391 } 3392 3393 } 3394 3395 #ifndef WITHOUT_PKCS11 3396 static krb5_error_code 3397 load_pkcs11_module(krb5_context context, const char *modname, 3398 struct plugin_file_handle **handle_out, 3399 CK_FUNCTION_LIST_PTR_PTR p11_out) 3400 { 3401 struct plugin_file_handle *handle = NULL; 3402 CK_RV rv, (*getflist)(CK_FUNCTION_LIST_PTR_PTR); 3403 struct errinfo einfo = EMPTY_ERRINFO; 3404 const char *errmsg = NULL, *failure; 3405 void (*sym)(void); 3406 long err; 3407 3408 TRACE_PKINIT_PKCS11_OPEN(context, modname); 3409 err = krb5int_open_plugin(modname, &handle, &einfo); 3410 if (err) { 3411 failure = _("Cannot load PKCS11 module"); 3412 goto error; 3413 } 3414 3415 err = krb5int_get_plugin_func(handle, "C_GetFunctionList", &sym, &einfo); 3416 if (err) { 3417 failure = _("Cannot find C_GetFunctionList in PKCS11 module"); 3418 goto error; 3419 } 3420 3421 getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))sym; 3422 rv = (*getflist)(p11_out); 3423 if (rv != CKR_OK) { 3424 failure = _("Cannot retrieve function list in PKCS11 module"); 3425 goto error; 3426 } 3427 3428 *handle_out = handle; 3429 return 0; 3430 3431 error: 3432 if (err) { 3433 errmsg = k5_get_error(&einfo, err); 3434 k5_setmsg(context, err, _("%s: %s"), failure, errmsg); 3435 } else { 3436 err = KRB5KDC_ERR_PREAUTH_FAILED; 3437 k5_setmsg(context, err, "%s", failure); 3438 } 3439 k5_clear_error(&einfo); 3440 if (handle != NULL) 3441 krb5int_close_plugin(handle); 3442 return err; 3443 } 3444 3445 static krb5_error_code 3446 pkinit_login(krb5_context context, 3447 pkinit_identity_crypto_context id_cryptoctx, 3448 CK_TOKEN_INFO *tip, const char *password) 3449 { 3450 krb5_error_code ret = 0; 3451 CK_RV rv; 3452 krb5_data rdat; 3453 char *prompt; 3454 const char *warning; 3455 krb5_prompt kprompt; 3456 krb5_prompt_type prompt_type; 3457 3458 if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) { 3459 rdat.data = NULL; 3460 rdat.length = 0; 3461 } else if (password != NULL) { 3462 rdat.data = strdup(password); 3463 rdat.length = strlen(password); 3464 } else if (id_cryptoctx->prompter == NULL) { 3465 ret = KRB5_LIBOS_CANTREADPWD; 3466 rdat.data = NULL; 3467 } else { 3468 if (tip->flags & CKF_USER_PIN_LOCKED) 3469 warning = " (Warning: PIN locked)"; 3470 else if (tip->flags & CKF_USER_PIN_FINAL_TRY) 3471 warning = " (Warning: PIN final try)"; 3472 else if (tip->flags & CKF_USER_PIN_COUNT_LOW) 3473 warning = " (Warning: PIN count low)"; 3474 else 3475 warning = ""; 3476 if (asprintf(&prompt, "%.*s PIN%s", (int) sizeof (tip->label), 3477 tip->label, warning) < 0) 3478 return ENOMEM; 3479 rdat.data = malloc(tip->ulMaxPinLen + 2); 3480 rdat.length = tip->ulMaxPinLen + 1; 3481 3482 kprompt.prompt = prompt; 3483 kprompt.hidden = 1; 3484 kprompt.reply = &rdat; 3485 prompt_type = KRB5_PROMPT_TYPE_PREAUTH; 3486 3487 /* PROMPTER_INVOCATION */ 3488 k5int_set_prompt_types(context, &prompt_type); 3489 ret = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data, 3490 NULL, NULL, 1, &kprompt); 3491 k5int_set_prompt_types(context, 0); 3492 free(prompt); 3493 } 3494 3495 if (!ret) { 3496 rv = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER, 3497 (uint8_t *)rdat.data, rdat.length); 3498 if (rv != CKR_OK) 3499 ret = p11err(context, rv, "C_Login"); 3500 } 3501 free(rdat.data); 3502 3503 return ret; 3504 } 3505 3506 static krb5_error_code 3507 pkinit_open_session(krb5_context context, 3508 pkinit_identity_crypto_context cctx) 3509 { 3510 CK_ULONG i, rv; 3511 unsigned char *cp; 3512 size_t label_len; 3513 CK_ULONG count = 0; 3514 CK_SLOT_ID_PTR slotlist = NULL; 3515 CK_TOKEN_INFO tinfo; 3516 char *p11name = NULL; 3517 const char *password; 3518 krb5_error_code ret; 3519 3520 if (cctx->p11_module != NULL) 3521 return 0; /* session already open */ 3522 3523 /* Load module */ 3524 ret = load_pkcs11_module(context, cctx->p11_module_name, &cctx->p11_module, 3525 &cctx->p11); 3526 if (ret) 3527 goto cleanup; 3528 3529 /* Init */ 3530 rv = cctx->p11->C_Initialize(NULL); 3531 if (rv != CKR_OK) { 3532 ret = p11err(context, rv, "C_Initialize"); 3533 goto cleanup; 3534 } 3535 3536 /* Get the list of available slots */ 3537 rv = cctx->p11->C_GetSlotList(TRUE, NULL, &count); 3538 if (rv != CKR_OK) { 3539 ret = p11err(context, rv, "C_GetSlotList"); 3540 goto cleanup; 3541 } 3542 if (count == 0) { 3543 TRACE_PKINIT_PKCS11_NO_TOKEN(context); 3544 ret = KRB5KDC_ERR_PREAUTH_FAILED; 3545 goto cleanup; 3546 } 3547 slotlist = k5calloc(count, sizeof(CK_SLOT_ID), &ret); 3548 if (slotlist == NULL) 3549 goto cleanup; 3550 rv = cctx->p11->C_GetSlotList(TRUE, slotlist, &count); 3551 if (rv != CKR_OK) { 3552 ret = p11err(context, rv, "C_GetSlotList"); 3553 goto cleanup; 3554 } 3555 3556 /* Look for the given token label, or if none given take the first one */ 3557 for (i = 0; i < count; i++) { 3558 /* Skip slots that don't match the specified slotid, if given. */ 3559 if (cctx->slotid != PK_NOSLOT && cctx->slotid != slotlist[i]) 3560 continue; 3561 3562 /* Open session */ 3563 rv = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION, 3564 NULL, NULL, &cctx->session); 3565 if (rv != CKR_OK) { 3566 ret = p11err(context, rv, "C_OpenSession"); 3567 goto cleanup; 3568 } 3569 3570 /* Get token info */ 3571 rv = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo); 3572 if (rv != CKR_OK) { 3573 ret = p11err(context, rv, "C_GetTokenInfo"); 3574 goto cleanup; 3575 } 3576 3577 /* tinfo.label is zero-filled but not necessarily zero-terminated. 3578 * Find the length, ignoring any trailing spaces. */ 3579 for (cp = tinfo.label + sizeof(tinfo.label); cp > tinfo.label; cp--) { 3580 if (cp[-1] != '\0' && cp[-1] != ' ') 3581 break; 3582 } 3583 label_len = cp - tinfo.label; 3584 3585 TRACE_PKINIT_PKCS11_SLOT(context, (int)slotlist[i], (int)label_len, 3586 tinfo.label); 3587 if (cctx->token_label == NULL || 3588 (strlen(cctx->token_label) == label_len && 3589 memcmp(cctx->token_label, tinfo.label, label_len) == 0)) 3590 break; 3591 cctx->p11->C_CloseSession(cctx->session); 3592 } 3593 if (i >= count) { 3594 TRACE_PKINIT_PKCS11_NO_MATCH_TOKEN(context); 3595 ret = KRB5KDC_ERR_PREAUTH_FAILED; 3596 goto cleanup; 3597 } 3598 cctx->slotid = slotlist[i]; 3599 pkiDebug("open_session: slotid %d (%lu of %d)\n", (int)cctx->slotid, 3600 i + 1, (int) count); 3601 3602 /* Login if needed */ 3603 if (tinfo.flags & CKF_LOGIN_REQUIRED) { 3604 if (cctx->slotid != PK_NOSLOT) { 3605 if (asprintf(&p11name, 3606 "PKCS11:module_name=%s:slotid=%ld:token=%.*s", 3607 cctx->p11_module_name, (long)cctx->slotid, 3608 (int)label_len, tinfo.label) < 0) 3609 p11name = NULL; 3610 } else { 3611 if (asprintf(&p11name, 3612 "PKCS11:module_name=%s,token=%.*s", 3613 cctx->p11_module_name, 3614 (int)label_len, tinfo.label) < 0) 3615 p11name = NULL; 3616 } 3617 if (p11name == NULL) { 3618 ret = ENOMEM; 3619 goto cleanup; 3620 } 3621 if (cctx->defer_id_prompt) { 3622 /* Supply the identity name to be passed to the responder. */ 3623 pkinit_set_deferred_id(&cctx->deferred_ids, 3624 p11name, tinfo.flags, NULL); 3625 ret = 0; 3626 goto cleanup; 3627 } 3628 /* Look up a responder-supplied password for the token. */ 3629 password = pkinit_find_deferred_id(cctx->deferred_ids, p11name); 3630 ret = pkinit_login(context, cctx, &tinfo, password); 3631 if (ret) 3632 goto cleanup; 3633 } 3634 3635 ret = 0; 3636 cleanup: 3637 /* On error, finalize the PKCS11 fields to ensure that we don't mistakenly 3638 * short-circuit with success on the next call. */ 3639 if (ret) 3640 pkinit_fini_pkcs11(cctx); 3641 free(slotlist); 3642 free(p11name); 3643 return ret; 3644 } 3645 3646 /* 3647 * Look for a key that's: 3648 * 1. private 3649 * 2. capable of the specified operation (usually signing or decrypting) 3650 * 3. matches the id of the cert we chose 3651 * 3652 * You must call pkinit_get_certs before calling pkinit_find_private_key 3653 * (that's because we need the ID of the private key) 3654 * 3655 * pkcs11 says the id of the key doesn't have to match that of the cert, but 3656 * I can't figure out any other way to decide which key to use. 3657 * 3658 * We should only find one key that fits all the requirements. 3659 * If there are more than one, we just take the first one. 3660 */ 3661 3662 static krb5_error_code 3663 pkinit_find_private_key(krb5_context context, 3664 pkinit_identity_crypto_context id_cryptoctx, 3665 CK_ATTRIBUTE_TYPE usage, 3666 CK_OBJECT_HANDLE *objp) 3667 { 3668 CK_OBJECT_CLASS cls; 3669 CK_ATTRIBUTE attrs[4]; 3670 CK_ULONG count; 3671 CK_RV rv; 3672 unsigned int nattrs = 0; 3673 #ifdef PKINIT_USE_KEY_USAGE 3674 CK_BBOOL true_false; 3675 #endif 3676 3677 cls = CKO_PRIVATE_KEY; 3678 attrs[nattrs].type = CKA_CLASS; 3679 attrs[nattrs].pValue = &cls; 3680 attrs[nattrs].ulValueLen = sizeof cls; 3681 nattrs++; 3682 3683 #ifdef PKINIT_USE_KEY_USAGE 3684 /* 3685 * Some cards get confused if you try to specify a key usage, 3686 * so don't, and hope for the best. This will fail if you have 3687 * several keys with the same id and different usages but I have 3688 * not seen this on real cards. 3689 */ 3690 true_false = TRUE; 3691 attrs[nattrs].type = usage; 3692 attrs[nattrs].pValue = &true_false; 3693 attrs[nattrs].ulValueLen = sizeof true_false; 3694 nattrs++; 3695 #endif 3696 3697 attrs[nattrs].type = CKA_ID; 3698 attrs[nattrs].pValue = id_cryptoctx->cert_id; 3699 attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len; 3700 nattrs++; 3701 3702 rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, 3703 nattrs); 3704 if (rv != CKR_OK) 3705 return p11err(context, rv, _("C_FindObjectsInit")); 3706 3707 rv = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, 3708 &count); 3709 id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session); 3710 if (rv != CKR_OK) 3711 return p11err(context, rv, _("C_FindObjects")); 3712 if (count < 1) { 3713 k5_setmsg(context, KRB5KDC_ERR_PREAUTH_FAILED, 3714 _("Found no private keys in PKCS11 token")); 3715 return KRB5KDC_ERR_PREAUTH_FAILED; 3716 } 3717 return 0; 3718 } 3719 #endif 3720 3721 static krb5_error_code 3722 pkinit_sign_data_fs(krb5_context context, 3723 pkinit_identity_crypto_context id_cryptoctx, 3724 unsigned char *data, 3725 unsigned int data_len, 3726 unsigned char **sig, 3727 unsigned int *sig_len) 3728 { 3729 if (create_signature(sig, sig_len, data, data_len, 3730 id_cryptoctx->my_key) != 0) { 3731 pkiDebug("failed to create the signature\n"); 3732 return KRB5KDC_ERR_PREAUTH_FAILED; 3733 } 3734 return 0; 3735 } 3736 3737 #ifndef WITHOUT_PKCS11 3738 /* 3739 * DER-encode a DigestInfo sequence containing the algorithm md and the digest 3740 * mdbytes. 3741 * 3742 * DigestInfo ::= SEQUENCE { 3743 * digestAlgorithm AlgorithmIdentifier, 3744 * digest OCTET STRING 3745 * } 3746 */ 3747 static krb5_error_code 3748 encode_digestinfo(krb5_context context, const EVP_MD *md, 3749 const uint8_t *mdbytes, size_t mdlen, 3750 uint8_t **encoding_out, size_t *len_out) 3751 { 3752 krb5_boolean ok = FALSE; 3753 X509_ALGOR *alg = NULL; 3754 ASN1_OCTET_STRING *digest = NULL; 3755 uint8_t *buf, *p; 3756 int alg_len, digest_len, len; 3757 3758 *encoding_out = NULL; 3759 *len_out = 0; 3760 3761 alg = X509_ALGOR_new(); 3762 if (alg == NULL || 3763 !X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_nid(md)), V_ASN1_NULL, NULL)) 3764 goto cleanup; 3765 alg_len = i2d_X509_ALGOR(alg, NULL); 3766 if (alg_len < 0) 3767 goto cleanup; 3768 3769 digest = ASN1_OCTET_STRING_new(); 3770 if (digest == NULL || !ASN1_OCTET_STRING_set(digest, mdbytes, mdlen)) 3771 goto cleanup; 3772 digest_len = i2d_ASN1_OCTET_STRING(digest, NULL); 3773 if (digest_len < 0) 3774 goto cleanup; 3775 3776 len = ASN1_object_size(1, alg_len + digest_len, V_ASN1_SEQUENCE); 3777 p = buf = malloc(len); 3778 if (buf == NULL) 3779 goto cleanup; 3780 ASN1_put_object(&p, 1, alg_len + digest_len, V_ASN1_SEQUENCE, 3781 V_ASN1_UNIVERSAL); 3782 i2d_X509_ALGOR(alg, &p); 3783 i2d_ASN1_OCTET_STRING(digest, &p); 3784 3785 *encoding_out = buf; 3786 *len_out = len; 3787 ok = TRUE; 3788 3789 cleanup: 3790 X509_ALGOR_free(alg); 3791 ASN1_OCTET_STRING_free(digest); 3792 if (!ok) 3793 return oerr(context, 0, _("Failed to DER encode DigestInfo")); 3794 return 0; 3795 } 3796 3797 /* Extract the r and s values from a PKCS11 ECDSA signature and re-encode them 3798 * in the DER representation of an ECDSA-Sig-Value for use in CMS. */ 3799 static krb5_error_code 3800 convert_pkcs11_ecdsa_sig(krb5_context context, 3801 const uint8_t *p11sig, unsigned int p11siglen, 3802 uint8_t **sig_out, unsigned int *sig_len_out) 3803 { 3804 krb5_boolean ok = FALSE; 3805 BIGNUM *r = NULL, *s = NULL; 3806 ECDSA_SIG *sig = NULL; 3807 int len; 3808 uint8_t *p; 3809 3810 *sig_out = NULL; 3811 *sig_len_out = 0; 3812 3813 if (p11siglen % 2 != 0) 3814 return EINVAL; 3815 3816 /* Extract the r and s values from the PKCS11 signature. */ 3817 r = BN_bin2bn(p11sig, p11siglen / 2, NULL); 3818 s = BN_bin2bn(p11sig + p11siglen / 2, p11siglen / 2, NULL); 3819 if (r == NULL || s == NULL) 3820 goto cleanup; 3821 3822 /* Create an ECDSA-Sig-Value object and transfer ownership of r and s. */ 3823 sig = ECDSA_SIG_new(); 3824 if (sig == NULL || !ECDSA_SIG_set0(sig, r, s)) 3825 goto cleanup; 3826 r = s = NULL; 3827 3828 /* DER-encode the ECDSA-Sig-Value object. */ 3829 len = i2d_ECDSA_SIG(sig, NULL); 3830 if (len < 0) 3831 goto cleanup; 3832 p = *sig_out = malloc(len); 3833 if (*sig_out == NULL) 3834 goto cleanup; 3835 *sig_len_out = len; 3836 i2d_ECDSA_SIG(sig, &p); 3837 ok = TRUE; 3838 3839 cleanup: 3840 BN_free(r); 3841 BN_free(s); 3842 ECDSA_SIG_free(sig); 3843 if (!ok) 3844 return oerr(context, 0, _("Failed to convert PKCS11 ECDSA signature")); 3845 return 0; 3846 } 3847 3848 static krb5_error_code 3849 pkinit_sign_data_pkcs11(krb5_context context, 3850 pkinit_identity_crypto_context id_cryptoctx, 3851 unsigned char *data, 3852 unsigned int data_len, 3853 unsigned char **sig, 3854 unsigned int *sig_len) 3855 { 3856 krb5_error_code ret; 3857 CK_OBJECT_HANDLE obj; 3858 CK_ULONG len; 3859 CK_MECHANISM mech; 3860 CK_SESSION_HANDLE session; 3861 CK_FUNCTION_LIST_PTR p11; 3862 CK_ATTRIBUTE attr; 3863 CK_KEY_TYPE keytype; 3864 CK_RV rv; 3865 EVP_MD_CTX *ctx; 3866 const EVP_MD *md = EVP_sha256(); 3867 unsigned int mdlen; 3868 uint8_t mdbuf[EVP_MAX_MD_SIZE], *dinfo = NULL, *sigbuf = NULL, *input; 3869 size_t dinfo_len, input_len; 3870 3871 *sig = NULL; 3872 *sig_len = 0; 3873 3874 ret = pkinit_open_session(context, id_cryptoctx); 3875 if (ret) 3876 return ret; 3877 p11 = id_cryptoctx->p11; 3878 session = id_cryptoctx->session; 3879 3880 ret = pkinit_find_private_key(context, id_cryptoctx, CKA_SIGN, &obj); 3881 if (ret) 3882 return ret; 3883 3884 attr.type = CKA_KEY_TYPE; 3885 attr.pValue = &keytype; 3886 attr.ulValueLen = sizeof(keytype); 3887 rv = p11->C_GetAttributeValue(session, obj, &attr, 1); 3888 if (rv != CKR_OK) { 3889 ret = p11err(context, rv, "C_GetAttributeValue"); 3890 goto cleanup; 3891 } 3892 3893 /* 3894 * We would ideally use CKM_SHA256_RSA_PKCS and CKM_ECDSA_SHA256, but 3895 * historically many cards seem to be confused about whether they are 3896 * capable of mechanisms or not. To be safe we compute the digest 3897 * ourselves and use CKM_RSA_PKCS and CKM_ECDSA. 3898 */ 3899 ctx = EVP_MD_CTX_new(); 3900 if (ctx == NULL) { 3901 ret = KRB5KDC_ERR_PREAUTH_FAILED; 3902 goto cleanup; 3903 } 3904 EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); 3905 EVP_DigestUpdate(ctx, data, data_len); 3906 EVP_DigestFinal_ex(ctx, mdbuf, &mdlen); 3907 EVP_MD_CTX_free(ctx); 3908 3909 if (keytype == CKK_RSA) { 3910 /* For RSA we must also encode the digest in a DigestInfo sequence. */ 3911 mech.mechanism = CKM_RSA_PKCS; 3912 ret = encode_digestinfo(context, md, mdbuf, mdlen, &dinfo, &dinfo_len); 3913 if (ret) 3914 goto cleanup; 3915 input = dinfo; 3916 input_len = dinfo_len; 3917 } else if (keytype == CKK_EC) { 3918 mech.mechanism = CKM_ECDSA; 3919 input = mdbuf; 3920 input_len = mdlen; 3921 } else { 3922 ret = KRB5KDC_ERR_PREAUTH_FAILED; 3923 k5_setmsg(context, ret, 3924 _("PKCS11 certificate has unsupported key type %lu"), 3925 keytype); 3926 goto cleanup; 3927 } 3928 mech.pParameter = NULL; 3929 mech.ulParameterLen = 0; 3930 3931 rv = p11->C_SignInit(session, &mech, obj); 3932 if (rv != CKR_OK) { 3933 ret = p11err(context, rv, "C_SignInit"); 3934 goto cleanup; 3935 } 3936 3937 /* 3938 * Key len would give an upper bound on sig size, but there's no way to 3939 * get that. So guess, and if it's too small, re-malloc. 3940 */ 3941 len = PK_SIGLEN_GUESS; 3942 sigbuf = k5alloc(len, &ret); 3943 if (sigbuf == NULL) 3944 goto cleanup; 3945 3946 rv = p11->C_Sign(session, input, input_len, sigbuf, &len); 3947 if (rv == CKR_BUFFER_TOO_SMALL || 3948 (rv == CKR_OK && len >= PK_SIGLEN_GUESS)) { 3949 free(sigbuf); 3950 sigbuf = k5alloc(len, &ret); 3951 if (sigbuf == NULL) 3952 goto cleanup; 3953 rv = p11->C_Sign(session, input, input_len, sigbuf, &len); 3954 } 3955 if (rv != CKR_OK) { 3956 ret = p11err(context, rv, "C_Sign"); 3957 goto cleanup; 3958 } 3959 3960 if (keytype == CKK_EC) { 3961 /* PKCS11 ECDSA signatures must be re-encoded for CMS. */ 3962 ret = convert_pkcs11_ecdsa_sig(context, sigbuf, len, sig, sig_len); 3963 } else { 3964 *sig_len = len; 3965 *sig = sigbuf; 3966 sigbuf = NULL; 3967 } 3968 3969 cleanup: 3970 free(dinfo); 3971 free(sigbuf); 3972 return ret; 3973 } 3974 #endif 3975 3976 krb5_error_code 3977 pkinit_sign_data(krb5_context context, 3978 pkinit_identity_crypto_context id_cryptoctx, 3979 unsigned char *data, 3980 unsigned int data_len, 3981 unsigned char **sig, 3982 unsigned int *sig_len) 3983 { 3984 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 3985 3986 if (id_cryptoctx == NULL || id_cryptoctx->pkcs11_method != 1) 3987 retval = pkinit_sign_data_fs(context, id_cryptoctx, data, data_len, 3988 sig, sig_len); 3989 #ifndef WITHOUT_PKCS11 3990 else 3991 retval = pkinit_sign_data_pkcs11(context, id_cryptoctx, data, data_len, 3992 sig, sig_len); 3993 #endif 3994 3995 return retval; 3996 } 3997 3998 3999 static krb5_error_code 4000 create_signature(unsigned char **sig, unsigned int *sig_len, 4001 unsigned char *data, unsigned int data_len, EVP_PKEY *pkey) 4002 { 4003 krb5_error_code retval = ENOMEM; 4004 EVP_MD_CTX *ctx; 4005 4006 if (pkey == NULL) 4007 return retval; 4008 4009 ctx = EVP_MD_CTX_new(); 4010 if (ctx == NULL) 4011 return ENOMEM; 4012 EVP_SignInit(ctx, EVP_sha256()); 4013 EVP_SignUpdate(ctx, data, data_len); 4014 *sig_len = EVP_PKEY_size(pkey); 4015 if ((*sig = malloc(*sig_len)) == NULL) 4016 goto cleanup; 4017 EVP_SignFinal(ctx, *sig, sig_len, pkey); 4018 4019 retval = 0; 4020 4021 cleanup: 4022 EVP_MD_CTX_free(ctx); 4023 4024 return retval; 4025 } 4026 4027 /* 4028 * Note: 4029 * This is not the routine the KDC uses to get its certificate. 4030 * This routine is intended to be called by the client 4031 * to obtain the KDC's certificate from some local storage 4032 * to be sent as a hint in its request to the KDC. 4033 */ 4034 krb5_error_code 4035 pkinit_get_kdc_cert(krb5_context context, 4036 pkinit_plg_crypto_context plg_cryptoctx, 4037 pkinit_req_crypto_context req_cryptoctx, 4038 pkinit_identity_crypto_context id_cryptoctx, 4039 krb5_principal princ) 4040 { 4041 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 4042 4043 req_cryptoctx->received_cert = NULL; 4044 retval = 0; 4045 return retval; 4046 } 4047 4048 static char * 4049 reassemble_pkcs12_name(const char *filename) 4050 { 4051 char *ret; 4052 4053 if (asprintf(&ret, "PKCS12:%s", filename) < 0) 4054 return NULL; 4055 return ret; 4056 } 4057 4058 static krb5_error_code 4059 pkinit_get_certs_pkcs12(krb5_context context, 4060 pkinit_plg_crypto_context plg_cryptoctx, 4061 pkinit_req_crypto_context req_cryptoctx, 4062 pkinit_identity_opts *idopts, 4063 pkinit_identity_crypto_context id_cryptoctx, 4064 krb5_principal princ) 4065 { 4066 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 4067 char *prompt_string = NULL; 4068 X509 *x = NULL; 4069 PKCS12 *p12 = NULL; 4070 int ret; 4071 FILE *fp; 4072 EVP_PKEY *y = NULL; 4073 4074 if (idopts->cert_filename == NULL) { 4075 pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__); 4076 goto cleanup; 4077 } 4078 4079 if (idopts->key_filename == NULL) { 4080 pkiDebug("%s: failed to get user's private key location\n", __FUNCTION__); 4081 goto cleanup; 4082 } 4083 4084 fp = fopen(idopts->cert_filename, "rb"); 4085 if (fp == NULL) { 4086 TRACE_PKINIT_PKCS_OPEN_FAIL(context, idopts->cert_filename, errno); 4087 goto cleanup; 4088 } 4089 set_cloexec_file(fp); 4090 4091 p12 = d2i_PKCS12_fp(fp, NULL); 4092 fclose(fp); 4093 if (p12 == NULL) { 4094 TRACE_PKINIT_PKCS_DECODE_FAIL(context, idopts->cert_filename); 4095 goto cleanup; 4096 } 4097 /* 4098 * Try parsing with no pass phrase first. If that fails, 4099 * prompt for the pass phrase and try again. 4100 */ 4101 ret = PKCS12_parse(p12, NULL, &y, &x, NULL); 4102 if (ret == 0) { 4103 krb5_data rdat; 4104 krb5_prompt kprompt; 4105 krb5_prompt_type prompt_type; 4106 krb5_error_code r; 4107 char prompt_reply[128]; 4108 char *prompt_prefix = _("Pass phrase for"); 4109 char *p12name = reassemble_pkcs12_name(idopts->cert_filename); 4110 const char *tmp; 4111 4112 TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(context); 4113 4114 if (p12name == NULL) 4115 goto cleanup; 4116 if (id_cryptoctx->defer_id_prompt) { 4117 /* Supply the identity name to be passed to the responder. */ 4118 pkinit_set_deferred_id(&id_cryptoctx->deferred_ids, p12name, 0, 4119 NULL); 4120 free(p12name); 4121 retval = 0; 4122 goto cleanup; 4123 } 4124 /* Try to read a responder-supplied password. */ 4125 tmp = pkinit_find_deferred_id(id_cryptoctx->deferred_ids, p12name); 4126 free(p12name); 4127 if (tmp != NULL) { 4128 /* Try using the responder-supplied password. */ 4129 rdat.data = (char *)tmp; 4130 rdat.length = strlen(tmp); 4131 } else if (id_cryptoctx->prompter == NULL) { 4132 /* We can't use a prompter. */ 4133 goto cleanup; 4134 } else { 4135 /* Ask using a prompter. */ 4136 memset(prompt_reply, '\0', sizeof(prompt_reply)); 4137 rdat.data = prompt_reply; 4138 rdat.length = sizeof(prompt_reply); 4139 4140 if (asprintf(&prompt_string, "%s %s", prompt_prefix, 4141 idopts->cert_filename) < 0) { 4142 prompt_string = NULL; 4143 goto cleanup; 4144 } 4145 kprompt.prompt = prompt_string; 4146 kprompt.hidden = 1; 4147 kprompt.reply = &rdat; 4148 prompt_type = KRB5_PROMPT_TYPE_PREAUTH; 4149 /* PROMPTER_INVOCATION */ 4150 k5int_set_prompt_types(context, &prompt_type); 4151 r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data, 4152 NULL, NULL, 1, &kprompt); 4153 k5int_set_prompt_types(context, 0); 4154 if (r) { 4155 TRACE_PKINIT_PKCS_PROMPT_FAIL(context); 4156 goto cleanup; 4157 } 4158 } 4159 4160 ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL); 4161 if (ret == 0) { 4162 TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(context); 4163 goto cleanup; 4164 } 4165 } 4166 id_cryptoctx->creds[0] = malloc(sizeof(struct _pkinit_cred_info)); 4167 if (id_cryptoctx->creds[0] == NULL) 4168 goto cleanup; 4169 id_cryptoctx->creds[0]->name = 4170 reassemble_pkcs12_name(idopts->cert_filename); 4171 id_cryptoctx->creds[0]->cert = x; 4172 #ifndef WITHOUT_PKCS11 4173 id_cryptoctx->creds[0]->cert_id = NULL; 4174 id_cryptoctx->creds[0]->cert_id_len = 0; 4175 #endif 4176 id_cryptoctx->creds[0]->key = y; 4177 id_cryptoctx->creds[1] = NULL; 4178 4179 retval = 0; 4180 4181 cleanup: 4182 free(prompt_string); 4183 if (p12) 4184 PKCS12_free(p12); 4185 if (retval) { 4186 if (x != NULL) 4187 X509_free(x); 4188 if (y != NULL) 4189 EVP_PKEY_free(y); 4190 } 4191 return retval; 4192 } 4193 4194 static char * 4195 reassemble_files_name(const char *certfile, const char *keyfile) 4196 { 4197 char *ret; 4198 4199 if (keyfile != NULL) { 4200 if (asprintf(&ret, "FILE:%s,%s", certfile, keyfile) < 0) 4201 return NULL; 4202 } else { 4203 if (asprintf(&ret, "FILE:%s", certfile) < 0) 4204 return NULL; 4205 } 4206 return ret; 4207 } 4208 4209 static krb5_error_code 4210 pkinit_load_fs_cert_and_key(krb5_context context, 4211 pkinit_identity_crypto_context id_cryptoctx, 4212 char *certname, 4213 char *keyname, 4214 int cindex) 4215 { 4216 krb5_error_code retval; 4217 X509 *x = NULL; 4218 EVP_PKEY *y = NULL; 4219 char *fsname = NULL; 4220 const char *password; 4221 4222 fsname = reassemble_files_name(certname, keyname); 4223 4224 /* Try to read a responder-supplied password. */ 4225 password = pkinit_find_deferred_id(id_cryptoctx->deferred_ids, fsname); 4226 4227 /* Load the certificate. */ 4228 retval = get_cert(certname, &x); 4229 if (retval) { 4230 retval = oerr(context, retval, _("Cannot read certificate file '%s'"), 4231 certname); 4232 } 4233 if (retval || x == NULL) 4234 goto cleanup; 4235 /* Load the key. */ 4236 retval = get_key(context, id_cryptoctx, keyname, fsname, &y, password); 4237 if (retval) 4238 retval = oerr(context, retval, _("Cannot read key file '%s'"), fsname); 4239 if (retval || y == NULL) 4240 goto cleanup; 4241 4242 id_cryptoctx->creds[cindex] = malloc(sizeof(struct _pkinit_cred_info)); 4243 if (id_cryptoctx->creds[cindex] == NULL) { 4244 retval = ENOMEM; 4245 goto cleanup; 4246 } 4247 id_cryptoctx->creds[cindex]->name = reassemble_files_name(certname, 4248 keyname); 4249 id_cryptoctx->creds[cindex]->cert = x; 4250 #ifndef WITHOUT_PKCS11 4251 id_cryptoctx->creds[cindex]->cert_id = NULL; 4252 id_cryptoctx->creds[cindex]->cert_id_len = 0; 4253 #endif 4254 id_cryptoctx->creds[cindex]->key = y; 4255 id_cryptoctx->creds[cindex+1] = NULL; 4256 4257 retval = 0; 4258 4259 cleanup: 4260 free(fsname); 4261 if (retval != 0 || y == NULL) { 4262 if (x != NULL) 4263 X509_free(x); 4264 if (y != NULL) 4265 EVP_PKEY_free(y); 4266 } 4267 return retval; 4268 } 4269 4270 static krb5_error_code 4271 pkinit_get_certs_fs(krb5_context context, 4272 pkinit_plg_crypto_context plg_cryptoctx, 4273 pkinit_req_crypto_context req_cryptoctx, 4274 pkinit_identity_opts *idopts, 4275 pkinit_identity_crypto_context id_cryptoctx, 4276 krb5_principal princ) 4277 { 4278 krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; 4279 4280 if (idopts->cert_filename == NULL) { 4281 pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__); 4282 goto cleanup; 4283 } 4284 4285 if (idopts->key_filename == NULL) { 4286 TRACE_PKINIT_NO_PRIVKEY(context); 4287 goto cleanup; 4288 } 4289 4290 retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx, 4291 idopts->cert_filename, 4292 idopts->key_filename, 0); 4293 cleanup: 4294 return retval; 4295 } 4296 4297 static krb5_error_code 4298 pkinit_get_certs_dir(krb5_context context, 4299 pkinit_plg_crypto_context plg_cryptoctx, 4300 pkinit_req_crypto_context req_cryptoctx, 4301 pkinit_identity_opts *idopts, 4302 pkinit_identity_crypto_context id_cryptoctx, 4303 krb5_principal princ) 4304 { 4305 krb5_error_code retval = ENOMEM; 4306 int ncreds = 0, len, i; 4307 char *dirname, *suf, *name, **fnames = NULL; 4308 char *certname = NULL, *keyname = NULL; 4309 4310 if (idopts->cert_filename == NULL) { 4311 TRACE_PKINIT_NO_CERT(context); 4312 return ENOENT; 4313 } 4314 4315 dirname = idopts->cert_filename; 4316 retval = k5_dir_filenames(dirname, &fnames); 4317 if (retval) 4318 return retval; 4319 4320 /* 4321 * We'll assume that certs are named XXX.crt and the corresponding 4322 * key is named XXX.key 4323 */ 4324 for (i = 0; fnames[i] != NULL; i++) { 4325 /* Ignore anything starting with a dot */ 4326 name = fnames[i]; 4327 if (name[0] == '.') 4328 continue; 4329 len = strlen(name); 4330 if (len < 5) 4331 continue; 4332 suf = name + (len - 4); 4333 if (strncmp(suf, ".crt", 4) != 0) 4334 continue; 4335 4336 retval = k5_path_join(dirname, name, &certname); 4337 if (retval) 4338 goto cleanup; 4339 retval = k5_path_join(dirname, name, &keyname); 4340 if (retval) 4341 goto cleanup; 4342 4343 len = strlen(keyname); 4344 keyname[len - 3] = 'k'; 4345 keyname[len - 2] = 'e'; 4346 keyname[len - 1] = 'y'; 4347 4348 retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx, 4349 certname, keyname, ncreds); 4350 free(certname); 4351 free(keyname); 4352 certname = keyname = NULL; 4353 if (!retval) { 4354 TRACE_PKINIT_LOADED_CERT(context, name); 4355 if (++ncreds >= MAX_CREDS_ALLOWED) 4356 break; 4357 } 4358 } 4359 4360 if (!id_cryptoctx->defer_id_prompt && ncreds == 0) { 4361 TRACE_PKINIT_NO_CERT_AND_KEY(context, idopts->cert_filename); 4362 retval = ENOENT; 4363 goto cleanup; 4364 } 4365 4366 retval = 0; 4367 4368 cleanup: 4369 k5_free_filenames(fnames); 4370 free(certname); 4371 free(keyname); 4372 return retval; 4373 } 4374 4375 #ifndef WITHOUT_PKCS11 4376 static char * 4377 reassemble_pkcs11_name(pkinit_identity_opts *idopts) 4378 { 4379 struct k5buf buf; 4380 int n = 0; 4381 4382 k5_buf_init_dynamic(&buf); 4383 k5_buf_add(&buf, "PKCS11:"); 4384 n = 0; 4385 if (idopts->p11_module_name != NULL) { 4386 k5_buf_add_fmt(&buf, "%smodule_name=%s", n++ ? ":" : "", 4387 idopts->p11_module_name); 4388 } 4389 if (idopts->token_label != NULL) { 4390 k5_buf_add_fmt(&buf, "%stoken=%s", n++ ? ":" : "", 4391 idopts->token_label); 4392 } 4393 if (idopts->cert_label != NULL) { 4394 k5_buf_add_fmt(&buf, "%scertlabel=%s", n++ ? ":" : "", 4395 idopts->cert_label); 4396 } 4397 if (idopts->cert_id_string != NULL) { 4398 k5_buf_add_fmt(&buf, "%scertid=%s", n++ ? ":" : "", 4399 idopts->cert_id_string); 4400 } 4401 if (idopts->slotid != PK_NOSLOT) { 4402 k5_buf_add_fmt(&buf, "%sslotid=%ld", n++ ? ":" : "", 4403 (long)idopts->slotid); 4404 } 4405 return k5_buf_cstring(&buf); 4406 } 4407 4408 static krb5_error_code 4409 load_one_cert(krb5_context context, CK_FUNCTION_LIST_PTR p11, 4410 CK_SESSION_HANDLE session, pkinit_identity_opts *idopts, 4411 pkinit_cred_info *cred_out) 4412 { 4413 krb5_error_code ret; 4414 CK_ATTRIBUTE attrs[2]; 4415 CK_BYTE_PTR cert = NULL, cert_id = NULL; 4416 CK_RV rv; 4417 const unsigned char *cp; 4418 CK_OBJECT_HANDLE obj; 4419 CK_ULONG count; 4420 X509 *x = NULL; 4421 pkinit_cred_info cred; 4422 4423 *cred_out = NULL; 4424 4425 /* Look for X.509 cert. */ 4426 rv = p11->C_FindObjects(session, &obj, 1, &count); 4427 if (rv != CKR_OK || count <= 0) 4428 return 0; 4429 4430 /* Get cert and id len. */ 4431 attrs[0].type = CKA_VALUE; 4432 attrs[0].pValue = NULL; 4433 attrs[0].ulValueLen = 0; 4434 attrs[1].type = CKA_ID; 4435 attrs[1].pValue = NULL; 4436 attrs[1].ulValueLen = 0; 4437 rv = p11->C_GetAttributeValue(session, obj, attrs, 2); 4438 if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL) { 4439 ret = p11err(context, rv, "C_GetAttributeValue"); 4440 goto cleanup; 4441 } 4442 4443 /* Allocate buffers and read the cert and id. */ 4444 cert = k5alloc(attrs[0].ulValueLen + 1, &ret); 4445 if (cert == NULL) 4446 goto cleanup; 4447 cert_id = k5alloc(attrs[1].ulValueLen + 1, &ret); 4448 if (cert_id == NULL) 4449 goto cleanup; 4450 attrs[0].type = CKA_VALUE; 4451 attrs[0].pValue = cert; 4452 attrs[1].type = CKA_ID; 4453 attrs[1].pValue = cert_id; 4454 rv = p11->C_GetAttributeValue(session, obj, attrs, 2); 4455 if (rv != CKR_OK) { 4456 ret = p11err(context, rv, "C_GetAttributeValue"); 4457 goto cleanup; 4458 } 4459 4460 pkiDebug("cert: size %d, id %d, idlen %d\n", (int)attrs[0].ulValueLen, 4461 (int)cert_id[0], (int)attrs[1].ulValueLen); 4462 4463 cp = (unsigned char *)cert; 4464 x = d2i_X509(NULL, &cp, (int)attrs[0].ulValueLen); 4465 if (x == NULL) { 4466 ret = oerr(context, 0, 4467 _("Failed to decode X509 certificate from PKCS11 token")); 4468 goto cleanup; 4469 } 4470 4471 cred = k5alloc(sizeof(struct _pkinit_cred_info), &ret); 4472 if (cred == NULL) 4473 goto cleanup; 4474 4475 cred->name = reassemble_pkcs11_name(idopts); 4476 cred->cert = x; 4477 cred->key = NULL; 4478 cred->cert_id = cert_id; 4479 cred->cert_id_len = attrs[1].ulValueLen; 4480 4481 *cred_out = cred; 4482 cert_id = NULL; 4483 ret = 0; 4484 4485 cleanup: 4486 free(cert); 4487 free(cert_id); 4488 return ret; 4489 } 4490 4491 static krb5_error_code 4492 pkinit_get_certs_pkcs11(krb5_context context, 4493 pkinit_plg_crypto_context plg_cryptoctx, 4494 pkinit_req_crypto_context req_cryptoctx, 4495 pkinit_identity_opts *idopts, 4496 pkinit_identity_crypto_context id_cryptoctx, 4497 krb5_principal princ) 4498 { 4499 CK_OBJECT_CLASS cls; 4500 CK_ATTRIBUTE attrs[4]; 4501 CK_CERTIFICATE_TYPE certtype; 4502 int i; 4503 unsigned int nattrs; 4504 krb5_error_code ret; 4505 CK_RV rv; 4506 4507 /* Copy stuff from idopts -> id_cryptoctx */ 4508 if (idopts->p11_module_name != NULL) { 4509 free(id_cryptoctx->p11_module_name); 4510 id_cryptoctx->p11_module_name = strdup(idopts->p11_module_name); 4511 if (id_cryptoctx->p11_module_name == NULL) 4512 return ENOMEM; 4513 } 4514 if (idopts->token_label != NULL) { 4515 id_cryptoctx->token_label = strdup(idopts->token_label); 4516 if (id_cryptoctx->token_label == NULL) 4517 return ENOMEM; 4518 } 4519 if (idopts->cert_label != NULL) { 4520 id_cryptoctx->cert_label = strdup(idopts->cert_label); 4521 if (id_cryptoctx->cert_label == NULL) 4522 return ENOMEM; 4523 } 4524 /* Convert the ascii cert_id string into a binary blob */ 4525 if (idopts->cert_id_string != NULL) { 4526 ret = k5_hex_decode(idopts->cert_id_string, &id_cryptoctx->cert_id, 4527 &id_cryptoctx->cert_id_len); 4528 if (ret) { 4529 pkiDebug("Failed to convert certid string [%s]\n", 4530 idopts->cert_id_string); 4531 return ret; 4532 } 4533 } 4534 id_cryptoctx->slotid = idopts->slotid; 4535 id_cryptoctx->pkcs11_method = 1; 4536 4537 ret = pkinit_open_session(context, id_cryptoctx); 4538 if (ret) 4539 return ret; 4540 if (id_cryptoctx->defer_id_prompt) { 4541 /* 4542 * We need to reset all of the PKCS#11 state, so that the next time we 4543 * poke at it, it'll be in as close to the state it was in after we 4544 * loaded it the first time as we can make it. 4545 */ 4546 pkinit_fini_pkcs11(id_cryptoctx); 4547 pkinit_init_pkcs11(id_cryptoctx); 4548 return 0; 4549 } 4550 4551 cls = CKO_CERTIFICATE; 4552 attrs[0].type = CKA_CLASS; 4553 attrs[0].pValue = &cls; 4554 attrs[0].ulValueLen = sizeof(cls); 4555 4556 certtype = CKC_X_509; 4557 attrs[1].type = CKA_CERTIFICATE_TYPE; 4558 attrs[1].pValue = &certtype; 4559 attrs[1].ulValueLen = sizeof(certtype); 4560 4561 nattrs = 2; 4562 4563 /* If a cert id and/or label were given, use them too */ 4564 if (id_cryptoctx->cert_id_len > 0) { 4565 attrs[nattrs].type = CKA_ID; 4566 attrs[nattrs].pValue = id_cryptoctx->cert_id; 4567 attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len; 4568 nattrs++; 4569 } 4570 if (id_cryptoctx->cert_label != NULL) { 4571 attrs[nattrs].type = CKA_LABEL; 4572 attrs[nattrs].pValue = id_cryptoctx->cert_label; 4573 attrs[nattrs].ulValueLen = strlen(id_cryptoctx->cert_label); 4574 nattrs++; 4575 } 4576 4577 rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, 4578 nattrs); 4579 if (rv != CKR_OK) { 4580 ret = p11err(context, rv, "C_FindObjectsInit"); 4581 return KRB5KDC_ERR_PREAUTH_FAILED; 4582 } 4583 4584 for (i = 0; i < MAX_CREDS_ALLOWED; i++) { 4585 ret = load_one_cert(context, id_cryptoctx->p11, id_cryptoctx->session, 4586 idopts, &id_cryptoctx->creds[i]); 4587 if (ret) 4588 return ret; 4589 if (id_cryptoctx->creds[i] == NULL) 4590 break; 4591 } 4592 if (i == MAX_CREDS_ALLOWED) 4593 return KRB5KDC_ERR_PREAUTH_FAILED; 4594 4595 id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session); 4596 4597 /* Check if we found no certs. */ 4598 if (id_cryptoctx->creds[0] == NULL) 4599 return KRB5KDC_ERR_PREAUTH_FAILED; 4600 return 0; 4601 } 4602 4603 #endif /* !WITHOUT_PKCS11 */ 4604 4605 4606 static void 4607 free_cred_info(krb5_context context, 4608 pkinit_identity_crypto_context id_cryptoctx, 4609 struct _pkinit_cred_info *cred) 4610 { 4611 if (cred != NULL) { 4612 if (cred->cert != NULL) 4613 X509_free(cred->cert); 4614 if (cred->key != NULL) 4615 EVP_PKEY_free(cred->key); 4616 #ifndef WITHOUT_PKCS11 4617 free(cred->cert_id); 4618 #endif 4619 free(cred->name); 4620 free(cred); 4621 } 4622 } 4623 4624 krb5_error_code 4625 crypto_free_cert_info(krb5_context context, 4626 pkinit_plg_crypto_context plg_cryptoctx, 4627 pkinit_req_crypto_context req_cryptoctx, 4628 pkinit_identity_crypto_context id_cryptoctx) 4629 { 4630 int i; 4631 4632 if (id_cryptoctx == NULL) 4633 return EINVAL; 4634 4635 for (i = 0; i < MAX_CREDS_ALLOWED; i++) { 4636 if (id_cryptoctx->creds[i] != NULL) { 4637 free_cred_info(context, id_cryptoctx, id_cryptoctx->creds[i]); 4638 id_cryptoctx->creds[i] = NULL; 4639 } 4640 } 4641 return 0; 4642 } 4643 4644 krb5_error_code 4645 crypto_load_certs(krb5_context context, 4646 pkinit_plg_crypto_context plg_cryptoctx, 4647 pkinit_req_crypto_context req_cryptoctx, 4648 pkinit_identity_opts *idopts, 4649 pkinit_identity_crypto_context id_cryptoctx, 4650 krb5_principal princ, 4651 krb5_boolean defer_id_prompts) 4652 { 4653 krb5_error_code retval; 4654 4655 id_cryptoctx->defer_id_prompt = defer_id_prompts; 4656 4657 switch(idopts->idtype) { 4658 case IDTYPE_FILE: 4659 retval = pkinit_get_certs_fs(context, plg_cryptoctx, 4660 req_cryptoctx, idopts, 4661 id_cryptoctx, princ); 4662 break; 4663 case IDTYPE_DIR: 4664 retval = pkinit_get_certs_dir(context, plg_cryptoctx, 4665 req_cryptoctx, idopts, 4666 id_cryptoctx, princ); 4667 break; 4668 #ifndef WITHOUT_PKCS11 4669 case IDTYPE_PKCS11: 4670 retval = pkinit_get_certs_pkcs11(context, plg_cryptoctx, 4671 req_cryptoctx, idopts, 4672 id_cryptoctx, princ); 4673 break; 4674 #endif 4675 case IDTYPE_PKCS12: 4676 retval = pkinit_get_certs_pkcs12(context, plg_cryptoctx, 4677 req_cryptoctx, idopts, 4678 id_cryptoctx, princ); 4679 break; 4680 default: 4681 retval = EINVAL; 4682 } 4683 if (retval) 4684 goto cleanup; 4685 4686 cleanup: 4687 return retval; 4688 } 4689 4690 /* 4691 * Get certificate Key Usage and Extended Key Usage 4692 */ 4693 static krb5_error_code 4694 crypto_retrieve_X509_key_usage(krb5_context context, 4695 pkinit_plg_crypto_context plgcctx, 4696 pkinit_req_crypto_context reqcctx, 4697 X509 *x, 4698 unsigned int *ret_ku_bits, 4699 unsigned int *ret_eku_bits) 4700 { 4701 krb5_error_code retval = 0; 4702 int i; 4703 unsigned int eku_bits = 0, ku_bits = 0; 4704 ASN1_BIT_STRING *usage = NULL; 4705 4706 if (ret_ku_bits == NULL && ret_eku_bits == NULL) 4707 return EINVAL; 4708 4709 if (ret_eku_bits) 4710 *ret_eku_bits = 0; 4711 else { 4712 pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__); 4713 goto check_kus; 4714 } 4715 4716 /* Start with Extended Key usage */ 4717 i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1); 4718 if (i >= 0) { 4719 EXTENDED_KEY_USAGE *eku; 4720 4721 eku = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL); 4722 if (eku) { 4723 for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { 4724 ASN1_OBJECT *certoid; 4725 certoid = sk_ASN1_OBJECT_value(eku, i); 4726 if ((OBJ_cmp(certoid, plgcctx->id_pkinit_KPClientAuth)) == 0) 4727 eku_bits |= PKINIT_EKU_PKINIT; 4728 else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_ms_smartcard_login))) == 0) 4729 eku_bits |= PKINIT_EKU_MSSCLOGIN; 4730 else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_client_auth))) == 0) 4731 eku_bits |= PKINIT_EKU_CLIENTAUTH; 4732 else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_email_protect))) == 0) 4733 eku_bits |= PKINIT_EKU_EMAILPROTECTION; 4734 } 4735 EXTENDED_KEY_USAGE_free(eku); 4736 } 4737 } 4738 pkiDebug("%s: returning eku 0x%08x\n", __FUNCTION__, eku_bits); 4739 *ret_eku_bits = eku_bits; 4740 4741 check_kus: 4742 /* Now the Key Usage bits */ 4743 if (ret_ku_bits) 4744 *ret_ku_bits = 0; 4745 else { 4746 pkiDebug("%s: KUs not requested, not checking\n", __FUNCTION__); 4747 goto out; 4748 } 4749 4750 /* Make sure usage exists before checking bits */ 4751 X509_check_ca(x); 4752 usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL); 4753 if (usage) { 4754 if (!ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) 4755 ku_bits |= PKINIT_KU_DIGITALSIGNATURE; 4756 if (!ku_reject(x, X509v3_KU_KEY_ENCIPHERMENT)) 4757 ku_bits |= PKINIT_KU_KEYENCIPHERMENT; 4758 ASN1_BIT_STRING_free(usage); 4759 } 4760 4761 pkiDebug("%s: returning ku 0x%08x\n", __FUNCTION__, ku_bits); 4762 *ret_ku_bits = ku_bits; 4763 retval = 0; 4764 out: 4765 return retval; 4766 } 4767 4768 static krb5_error_code 4769 rfc2253_name(X509_NAME *name, char **str_out) 4770 { 4771 BIO *b = NULL; 4772 char *str; 4773 4774 *str_out = NULL; 4775 b = BIO_new(BIO_s_mem()); 4776 if (b == NULL) 4777 return ENOMEM; 4778 if (X509_NAME_print_ex(b, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0) 4779 goto error; 4780 str = calloc(BIO_number_written(b) + 1, 1); 4781 if (str == NULL) 4782 goto error; 4783 BIO_read(b, str, BIO_number_written(b)); 4784 BIO_free(b); 4785 *str_out = str; 4786 return 0; 4787 4788 error: 4789 BIO_free(b); 4790 return ENOMEM; 4791 } 4792 4793 /* 4794 * Get number of certificates available after crypto_load_certs() 4795 */ 4796 static krb5_error_code 4797 crypto_cert_get_count(pkinit_identity_crypto_context id_cryptoctx, 4798 size_t *cert_count) 4799 { 4800 size_t count; 4801 4802 *cert_count = 0; 4803 if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL) 4804 return EINVAL; 4805 4806 for (count = 0; 4807 count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL; 4808 count++); 4809 *cert_count = count; 4810 return 0; 4811 } 4812 4813 void 4814 crypto_cert_free_matching_data(krb5_context context, 4815 pkinit_cert_matching_data *md) 4816 { 4817 size_t i; 4818 4819 if (md == NULL) 4820 return; 4821 free(md->subject_dn); 4822 free(md->issuer_dn); 4823 for (i = 0; md->sans != NULL && md->sans[i] != NULL; i++) 4824 krb5_free_principal(context, md->sans[i]); 4825 free(md->sans); 4826 for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) 4827 free(md->upns[i]); 4828 free(md->upns); 4829 free(md); 4830 } 4831 4832 /* 4833 * Free certificate matching data. 4834 */ 4835 void 4836 crypto_cert_free_matching_data_list(krb5_context context, 4837 pkinit_cert_matching_data **list) 4838 { 4839 size_t i; 4840 4841 for (i = 0; list != NULL && list[i] != NULL; i++) 4842 crypto_cert_free_matching_data(context, list[i]); 4843 free(list); 4844 } 4845 4846 /* 4847 * Get certificate matching data for cert. 4848 */ 4849 static krb5_error_code 4850 get_matching_data(krb5_context context, 4851 pkinit_plg_crypto_context plg_cryptoctx, 4852 pkinit_req_crypto_context req_cryptoctx, X509 *cert, 4853 pkinit_cert_matching_data **md_out) 4854 { 4855 krb5_error_code ret = ENOMEM; 4856 pkinit_cert_matching_data *md = NULL; 4857 4858 *md_out = NULL; 4859 4860 md = calloc(1, sizeof(*md)); 4861 if (md == NULL) 4862 goto cleanup; 4863 4864 ret = rfc2253_name(X509_get_subject_name(cert), &md->subject_dn); 4865 if (ret) 4866 goto cleanup; 4867 ret = rfc2253_name(X509_get_issuer_name(cert), &md->issuer_dn); 4868 if (ret) 4869 goto cleanup; 4870 4871 /* Get the SAN data. */ 4872 ret = crypto_retrieve_X509_sans(context, plg_cryptoctx, req_cryptoctx, 4873 cert, &md->sans, &md->upns, NULL); 4874 if (ret) 4875 goto cleanup; 4876 4877 /* Get the KU and EKU data. */ 4878 ret = crypto_retrieve_X509_key_usage(context, plg_cryptoctx, 4879 req_cryptoctx, cert, &md->ku_bits, 4880 &md->eku_bits); 4881 if (ret) 4882 goto cleanup; 4883 4884 *md_out = md; 4885 md = NULL; 4886 4887 cleanup: 4888 crypto_cert_free_matching_data(context, md); 4889 return ret; 4890 } 4891 4892 krb5_error_code 4893 crypto_cert_get_matching_data(krb5_context context, 4894 pkinit_plg_crypto_context plg_cryptoctx, 4895 pkinit_req_crypto_context req_cryptoctx, 4896 pkinit_identity_crypto_context id_cryptoctx, 4897 pkinit_cert_matching_data ***md_out) 4898 { 4899 krb5_error_code ret; 4900 pkinit_cert_matching_data **md_list = NULL; 4901 size_t count, i; 4902 4903 ret = crypto_cert_get_count(id_cryptoctx, &count); 4904 if (ret) 4905 goto cleanup; 4906 4907 md_list = calloc(count + 1, sizeof(*md_list)); 4908 if (md_list == NULL) { 4909 ret = ENOMEM; 4910 goto cleanup; 4911 } 4912 4913 for (i = 0; i < count; i++) { 4914 ret = get_matching_data(context, plg_cryptoctx, req_cryptoctx, 4915 id_cryptoctx->creds[i]->cert, &md_list[i]); 4916 if (ret) { 4917 pkiDebug("%s: crypto_cert_get_matching_data error %d, %s\n", 4918 __FUNCTION__, ret, error_message(ret)); 4919 goto cleanup; 4920 } 4921 } 4922 4923 *md_out = md_list; 4924 md_list = NULL; 4925 4926 cleanup: 4927 crypto_cert_free_matching_data_list(context, md_list); 4928 return ret; 4929 } 4930 4931 /* 4932 * Set the certificate in idctx->creds[cred_index] as the selected certificate, 4933 * stealing pointers from it. 4934 */ 4935 krb5_error_code 4936 crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx, 4937 size_t cred_index) 4938 { 4939 pkinit_cred_info ci = NULL; 4940 4941 if (cred_index >= MAX_CREDS_ALLOWED || idctx->creds[cred_index] == NULL) 4942 return ENOENT; 4943 4944 ci = idctx->creds[cred_index]; 4945 4946 idctx->my_cert = ci->cert; 4947 ci->cert = NULL; 4948 4949 /* hang on to the selected credential name */ 4950 free(idctx->identity); 4951 if (ci->name != NULL) 4952 idctx->identity = strdup(ci->name); 4953 else 4954 idctx->identity = NULL; 4955 4956 if (idctx->pkcs11_method != 1) { 4957 idctx->my_key = ci->key; 4958 ci->key = NULL; /* Don't free it twice */ 4959 } 4960 #ifndef WITHOUT_PKCS11 4961 else { 4962 idctx->cert_id = ci->cert_id; 4963 ci->cert_id = NULL; /* Don't free it twice */ 4964 idctx->cert_id_len = ci->cert_id_len; 4965 } 4966 #endif 4967 return 0; 4968 } 4969 4970 /* 4971 * Choose the default certificate as "the chosen one" 4972 */ 4973 krb5_error_code 4974 crypto_cert_select_default(krb5_context context, 4975 pkinit_plg_crypto_context plg_cryptoctx, 4976 pkinit_req_crypto_context req_cryptoctx, 4977 pkinit_identity_crypto_context id_cryptoctx) 4978 { 4979 krb5_error_code retval; 4980 size_t cert_count; 4981 4982 retval = crypto_cert_get_count(id_cryptoctx, &cert_count); 4983 if (retval) 4984 return retval; 4985 4986 if (cert_count != 1) { 4987 TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count); 4988 return EINVAL; 4989 } 4990 4991 return crypto_cert_select(context, id_cryptoctx, 0); 4992 } 4993 4994 4995 4996 static krb5_error_code 4997 load_cas_and_crls(krb5_context context, 4998 pkinit_plg_crypto_context plg_cryptoctx, 4999 pkinit_req_crypto_context req_cryptoctx, 5000 pkinit_identity_crypto_context id_cryptoctx, 5001 int catype, 5002 char *filename) 5003 { 5004 STACK_OF(X509_INFO) *sk = NULL; 5005 STACK_OF(X509) *ca_certs = NULL; 5006 STACK_OF(X509_CRL) *ca_crls = NULL; 5007 BIO *in = NULL; 5008 krb5_error_code retval = ENOMEM; 5009 int i = 0; 5010 5011 /* If there isn't already a stack in the context, 5012 * create a temporary one now */ 5013 switch(catype) { 5014 case CATYPE_ANCHORS: 5015 if (id_cryptoctx->trustedCAs != NULL) 5016 ca_certs = id_cryptoctx->trustedCAs; 5017 else { 5018 ca_certs = sk_X509_new_null(); 5019 if (ca_certs == NULL) 5020 return ENOMEM; 5021 } 5022 break; 5023 case CATYPE_INTERMEDIATES: 5024 if (id_cryptoctx->intermediateCAs != NULL) 5025 ca_certs = id_cryptoctx->intermediateCAs; 5026 else { 5027 ca_certs = sk_X509_new_null(); 5028 if (ca_certs == NULL) 5029 return ENOMEM; 5030 } 5031 break; 5032 case CATYPE_CRLS: 5033 if (id_cryptoctx->revoked != NULL) 5034 ca_crls = id_cryptoctx->revoked; 5035 else { 5036 ca_crls = sk_X509_CRL_new_null(); 5037 if (ca_crls == NULL) 5038 return ENOMEM; 5039 } 5040 break; 5041 default: 5042 return ENOTSUP; 5043 } 5044 5045 if (!(in = BIO_new_file(filename, "r"))) { 5046 retval = oerr(context, 0, _("Cannot open file '%s'"), filename); 5047 goto cleanup; 5048 } 5049 5050 /* This loads from a file, a stack of x509/crl/pkey sets */ 5051 if ((sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) { 5052 pkiDebug("%s: error reading file '%s'\n", __FUNCTION__, filename); 5053 retval = oerr(context, 0, _("Cannot read file '%s'"), filename); 5054 goto cleanup; 5055 } 5056 5057 /* scan over the stack created from loading the file contents, 5058 * weed out duplicates, and push new ones onto the return stack 5059 */ 5060 for (i = 0; i < sk_X509_INFO_num(sk); i++) { 5061 X509_INFO *xi = sk_X509_INFO_value(sk, i); 5062 if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) { 5063 int j = 0, size = sk_X509_num(ca_certs), flag = 0; 5064 5065 if (!size) { 5066 sk_X509_push(ca_certs, xi->x509); 5067 xi->x509 = NULL; 5068 continue; 5069 } 5070 for (j = 0; j < size; j++) { 5071 X509 *x = sk_X509_value(ca_certs, j); 5072 flag = X509_cmp(x, xi->x509); 5073 if (flag == 0) 5074 break; 5075 else 5076 continue; 5077 } 5078 if (flag != 0) { 5079 sk_X509_push(ca_certs, X509_dup(xi->x509)); 5080 } 5081 } else if (xi != NULL && xi->crl != NULL && catype == CATYPE_CRLS) { 5082 int j = 0, size = sk_X509_CRL_num(ca_crls), flag = 0; 5083 if (!size) { 5084 sk_X509_CRL_push(ca_crls, xi->crl); 5085 xi->crl = NULL; 5086 continue; 5087 } 5088 for (j = 0; j < size; j++) { 5089 X509_CRL *x = sk_X509_CRL_value(ca_crls, j); 5090 flag = X509_CRL_cmp(x, xi->crl); 5091 if (flag == 0) 5092 break; 5093 else 5094 continue; 5095 } 5096 if (flag != 0) { 5097 sk_X509_CRL_push(ca_crls, X509_CRL_dup(xi->crl)); 5098 } 5099 } 5100 } 5101 5102 /* If we added something and there wasn't a stack in the 5103 * context before, add the temporary stack to the context. 5104 */ 5105 switch(catype) { 5106 case CATYPE_ANCHORS: 5107 if (sk_X509_num(ca_certs) == 0) { 5108 TRACE_PKINIT_NO_CA_ANCHOR(context, filename); 5109 if (id_cryptoctx->trustedCAs == NULL) 5110 sk_X509_free(ca_certs); 5111 } else { 5112 if (id_cryptoctx->trustedCAs == NULL) 5113 id_cryptoctx->trustedCAs = ca_certs; 5114 } 5115 break; 5116 case CATYPE_INTERMEDIATES: 5117 if (sk_X509_num(ca_certs) == 0) { 5118 TRACE_PKINIT_NO_CA_INTERMEDIATE(context, filename); 5119 if (id_cryptoctx->intermediateCAs == NULL) 5120 sk_X509_free(ca_certs); 5121 } else { 5122 if (id_cryptoctx->intermediateCAs == NULL) 5123 id_cryptoctx->intermediateCAs = ca_certs; 5124 } 5125 break; 5126 case CATYPE_CRLS: 5127 if (sk_X509_CRL_num(ca_crls) == 0) { 5128 TRACE_PKINIT_NO_CRL(context, filename); 5129 if (id_cryptoctx->revoked == NULL) 5130 sk_X509_CRL_free(ca_crls); 5131 } else { 5132 if (id_cryptoctx->revoked == NULL) 5133 id_cryptoctx->revoked = ca_crls; 5134 } 5135 break; 5136 default: 5137 /* Should have been caught above! */ 5138 retval = EINVAL; 5139 goto cleanup; 5140 break; 5141 } 5142 5143 retval = 0; 5144 5145 cleanup: 5146 if (in != NULL) 5147 BIO_free(in); 5148 if (sk != NULL) 5149 sk_X509_INFO_pop_free(sk, X509_INFO_free); 5150 5151 return retval; 5152 } 5153 5154 static krb5_error_code 5155 load_cas_and_crls_dir(krb5_context context, 5156 pkinit_plg_crypto_context plg_cryptoctx, 5157 pkinit_req_crypto_context req_cryptoctx, 5158 pkinit_identity_crypto_context id_cryptoctx, 5159 int catype, 5160 char *dirname) 5161 { 5162 krb5_error_code retval = EINVAL; 5163 char **fnames = NULL, *filename; 5164 int i; 5165 5166 if (dirname == NULL) 5167 return EINVAL; 5168 5169 retval = k5_dir_filenames(dirname, &fnames); 5170 if (retval) 5171 return retval; 5172 5173 for (i = 0; fnames[i] != NULL; i++) { 5174 /* Ignore anything starting with a dot */ 5175 if (fnames[i][0] == '.') 5176 continue; 5177 5178 retval = k5_path_join(dirname, fnames[i], &filename); 5179 if (retval) 5180 goto cleanup; 5181 5182 retval = load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx, 5183 id_cryptoctx, catype, filename); 5184 free(filename); 5185 if (retval) 5186 goto cleanup; 5187 } 5188 5189 retval = 0; 5190 5191 cleanup: 5192 k5_free_filenames(fnames); 5193 return retval; 5194 } 5195 5196 krb5_error_code 5197 crypto_load_cas_and_crls(krb5_context context, 5198 pkinit_plg_crypto_context plg_cryptoctx, 5199 pkinit_req_crypto_context req_cryptoctx, 5200 pkinit_identity_opts *idopts, 5201 pkinit_identity_crypto_context id_cryptoctx, 5202 int idtype, 5203 int catype, 5204 char *id) 5205 { 5206 switch (idtype) { 5207 case IDTYPE_FILE: 5208 TRACE_PKINIT_LOAD_FROM_FILE(context, id); 5209 return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx, 5210 id_cryptoctx, catype, id); 5211 break; 5212 case IDTYPE_DIR: 5213 TRACE_PKINIT_LOAD_FROM_DIR(context, id); 5214 return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx, 5215 id_cryptoctx, catype, id); 5216 break; 5217 default: 5218 return ENOTSUP; 5219 break; 5220 } 5221 } 5222 5223 static krb5_error_code 5224 create_identifiers_from_stack(STACK_OF(X509) *sk, 5225 krb5_external_principal_identifier *** ids) 5226 { 5227 int i = 0, sk_size = sk_X509_num(sk); 5228 krb5_external_principal_identifier **krb5_cas = NULL; 5229 X509 *x = NULL; 5230 X509_NAME *xn = NULL; 5231 unsigned char *p = NULL; 5232 int len = 0; 5233 PKCS7_ISSUER_AND_SERIAL *is = NULL; 5234 char buf[DN_BUF_LEN]; 5235 5236 *ids = NULL; 5237 5238 krb5_cas = calloc(sk_size + 1, sizeof(*krb5_cas)); 5239 if (krb5_cas == NULL) 5240 return ENOMEM; 5241 5242 for (i = 0; i < sk_size; i++) { 5243 krb5_cas[i] = malloc(sizeof(krb5_external_principal_identifier)); 5244 5245 x = sk_X509_value(sk, i); 5246 5247 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf)); 5248 pkiDebug("#%d cert= %s\n", i, buf); 5249 5250 /* fill-in subjectName */ 5251 krb5_cas[i]->subjectName.magic = 0; 5252 krb5_cas[i]->subjectName.length = 0; 5253 krb5_cas[i]->subjectName.data = NULL; 5254 5255 xn = X509_get_subject_name(x); 5256 len = i2d_X509_NAME(xn, NULL); 5257 if ((p = malloc((size_t) len)) == NULL) 5258 goto oom; 5259 krb5_cas[i]->subjectName.data = (char *)p; 5260 i2d_X509_NAME(xn, &p); 5261 krb5_cas[i]->subjectName.length = len; 5262 5263 /* fill-in issuerAndSerialNumber */ 5264 krb5_cas[i]->issuerAndSerialNumber.length = 0; 5265 krb5_cas[i]->issuerAndSerialNumber.magic = 0; 5266 krb5_cas[i]->issuerAndSerialNumber.data = NULL; 5267 5268 is = PKCS7_ISSUER_AND_SERIAL_new(); 5269 if (is == NULL) 5270 goto oom; 5271 X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); 5272 ASN1_INTEGER_free(is->serial); 5273 is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x)); 5274 if (is->serial == NULL) 5275 goto oom; 5276 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); 5277 p = malloc(len); 5278 if (p == NULL) 5279 goto oom; 5280 krb5_cas[i]->issuerAndSerialNumber.data = (char *)p; 5281 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p); 5282 krb5_cas[i]->issuerAndSerialNumber.length = len; 5283 5284 /* fill-in subjectKeyIdentifier */ 5285 krb5_cas[i]->subjectKeyIdentifier.length = 0; 5286 krb5_cas[i]->subjectKeyIdentifier.magic = 0; 5287 krb5_cas[i]->subjectKeyIdentifier.data = NULL; 5288 5289 if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) { 5290 ASN1_OCTET_STRING *ikeyid; 5291 5292 ikeyid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, 5293 NULL); 5294 if (ikeyid != NULL) { 5295 len = i2d_ASN1_OCTET_STRING(ikeyid, NULL); 5296 p = malloc(len); 5297 if (p == NULL) 5298 goto oom; 5299 krb5_cas[i]->subjectKeyIdentifier.data = (char *)p; 5300 i2d_ASN1_OCTET_STRING(ikeyid, &p); 5301 krb5_cas[i]->subjectKeyIdentifier.length = len; 5302 ASN1_OCTET_STRING_free(ikeyid); 5303 } 5304 } 5305 PKCS7_ISSUER_AND_SERIAL_free(is); 5306 is = NULL; 5307 } 5308 5309 *ids = krb5_cas; 5310 return 0; 5311 5312 oom: 5313 free_krb5_external_principal_identifier(&krb5_cas); 5314 PKCS7_ISSUER_AND_SERIAL_free(is); 5315 return ENOMEM; 5316 } 5317 5318 static krb5_error_code 5319 create_krb5_invalidCertificates(krb5_context context, 5320 pkinit_plg_crypto_context plg_cryptoctx, 5321 pkinit_req_crypto_context req_cryptoctx, 5322 pkinit_identity_crypto_context id_cryptoctx, 5323 krb5_external_principal_identifier *** ids) 5324 { 5325 5326 krb5_error_code retval = ENOMEM; 5327 STACK_OF(X509) *sk = NULL; 5328 5329 *ids = NULL; 5330 if (req_cryptoctx->received_cert == NULL) 5331 return KRB5KDC_ERR_PREAUTH_FAILED; 5332 5333 sk = sk_X509_new_null(); 5334 if (sk == NULL) 5335 goto cleanup; 5336 sk_X509_push(sk, req_cryptoctx->received_cert); 5337 5338 retval = create_identifiers_from_stack(sk, ids); 5339 5340 sk_X509_free(sk); 5341 cleanup: 5342 5343 return retval; 5344 } 5345 5346 krb5_error_code 5347 create_krb5_supportedCMSTypes(krb5_context context, 5348 pkinit_plg_crypto_context plg_cryptoctx, 5349 pkinit_req_crypto_context req_cryptoctx, 5350 pkinit_identity_crypto_context id_cryptoctx, 5351 krb5_algorithm_identifier ***algs_out) 5352 { 5353 krb5_error_code ret; 5354 krb5_algorithm_identifier **algs = NULL; 5355 size_t i, count; 5356 5357 *algs_out = NULL; 5358 5359 /* Count supported OIDs and allocate list (including null terminator). */ 5360 for (count = 0; supported_cms_algs[count] != NULL; count++); 5361 algs = k5calloc(count + 1, sizeof(*algs), &ret); 5362 if (algs == NULL) 5363 goto cleanup; 5364 5365 /* Add an algorithm identifier for each OID, with no parameters. */ 5366 for (i = 0; i < count; i++) { 5367 algs[i] = k5alloc(sizeof(*algs[i]), &ret); 5368 if (algs[i] == NULL) 5369 goto cleanup; 5370 ret = krb5int_copy_data_contents(context, supported_cms_algs[i], 5371 &algs[i]->algorithm); 5372 if (ret) 5373 goto cleanup; 5374 algs[i]->parameters = empty_data(); 5375 } 5376 5377 *algs_out = algs; 5378 algs = NULL; 5379 5380 cleanup: 5381 free_krb5_algorithm_identifiers(&algs); 5382 return ret; 5383 } 5384 5385 krb5_error_code 5386 create_krb5_trustedCertifiers(krb5_context context, 5387 pkinit_plg_crypto_context plg_cryptoctx, 5388 pkinit_req_crypto_context req_cryptoctx, 5389 pkinit_identity_crypto_context id_cryptoctx, 5390 krb5_external_principal_identifier *** ids) 5391 { 5392 5393 krb5_error_code retval = ENOMEM; 5394 STACK_OF(X509) *sk = id_cryptoctx->trustedCAs; 5395 5396 *ids = NULL; 5397 if (id_cryptoctx->trustedCAs == NULL) 5398 return KRB5KDC_ERR_PREAUTH_FAILED; 5399 5400 retval = create_identifiers_from_stack(sk, ids); 5401 5402 return retval; 5403 } 5404 5405 krb5_error_code 5406 create_issuerAndSerial(krb5_context context, 5407 pkinit_plg_crypto_context plg_cryptoctx, 5408 pkinit_req_crypto_context req_cryptoctx, 5409 pkinit_identity_crypto_context id_cryptoctx, 5410 unsigned char **out, 5411 unsigned int *out_len) 5412 { 5413 unsigned char *p = NULL; 5414 PKCS7_ISSUER_AND_SERIAL *is = NULL; 5415 int len = 0; 5416 krb5_error_code retval = ENOMEM; 5417 X509 *cert = req_cryptoctx->received_cert; 5418 5419 *out = NULL; 5420 *out_len = 0; 5421 if (req_cryptoctx->received_cert == NULL) 5422 return 0; 5423 5424 is = PKCS7_ISSUER_AND_SERIAL_new(); 5425 X509_NAME_set(&is->issuer, X509_get_issuer_name(cert)); 5426 ASN1_INTEGER_free(is->serial); 5427 is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); 5428 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); 5429 if ((p = *out = malloc((size_t) len)) == NULL) 5430 goto cleanup; 5431 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p); 5432 *out_len = len; 5433 retval = 0; 5434 5435 cleanup: 5436 X509_NAME_free(is->issuer); 5437 ASN1_INTEGER_free(is->serial); 5438 free(is); 5439 5440 return retval; 5441 } 5442 5443 krb5_error_code 5444 pkinit_process_td_trusted_certifiers( 5445 krb5_context context, 5446 pkinit_plg_crypto_context plg_cryptoctx, 5447 pkinit_req_crypto_context req_cryptoctx, 5448 pkinit_identity_crypto_context id_cryptoctx, 5449 krb5_external_principal_identifier **krb5_trusted_certifiers, 5450 int td_type) 5451 { 5452 krb5_error_code retval = ENOMEM; 5453 STACK_OF(X509_NAME) *sk_xn = NULL; 5454 X509_NAME *xn = NULL; 5455 PKCS7_ISSUER_AND_SERIAL *is = NULL; 5456 ASN1_OCTET_STRING *id = NULL; 5457 const unsigned char *p = NULL; 5458 char buf[DN_BUF_LEN]; 5459 size_t i = 0; 5460 5461 if (td_type == TD_TRUSTED_CERTIFIERS) 5462 pkiDebug("received trusted certifiers\n"); 5463 else 5464 pkiDebug("received invalid certificate\n"); 5465 5466 sk_xn = sk_X509_NAME_new_null(); 5467 while(krb5_trusted_certifiers[i] != NULL) { 5468 if (krb5_trusted_certifiers[i]->subjectName.data != NULL) { 5469 p = (unsigned char *)krb5_trusted_certifiers[i]->subjectName.data; 5470 xn = d2i_X509_NAME(NULL, &p, 5471 (int)krb5_trusted_certifiers[i]->subjectName.length); 5472 if (xn == NULL) 5473 goto cleanup; 5474 X509_NAME_oneline(xn, buf, sizeof(buf)); 5475 if (td_type == TD_TRUSTED_CERTIFIERS) 5476 pkiDebug("#%d cert = %s is trusted by kdc\n", i, buf); 5477 else 5478 pkiDebug("#%d cert = %s is invalid\n", i, buf); 5479 sk_X509_NAME_push(sk_xn, xn); 5480 } 5481 5482 if (krb5_trusted_certifiers[i]->issuerAndSerialNumber.data != NULL) { 5483 p = (unsigned char *) 5484 krb5_trusted_certifiers[i]->issuerAndSerialNumber.data; 5485 is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, 5486 (int)krb5_trusted_certifiers[i]->issuerAndSerialNumber.length); 5487 if (is == NULL) 5488 goto cleanup; 5489 X509_NAME_oneline(is->issuer, buf, sizeof(buf)); 5490 if (td_type == TD_TRUSTED_CERTIFIERS) 5491 pkiDebug("#%d issuer = %s serial = %ld is trusted bu kdc\n", i, 5492 buf, ASN1_INTEGER_get(is->serial)); 5493 else 5494 pkiDebug("#%d issuer = %s serial = %ld is invalid\n", i, buf, 5495 ASN1_INTEGER_get(is->serial)); 5496 PKCS7_ISSUER_AND_SERIAL_free(is); 5497 } 5498 5499 if (krb5_trusted_certifiers[i]->subjectKeyIdentifier.data != NULL) { 5500 p = (unsigned char *) 5501 krb5_trusted_certifiers[i]->subjectKeyIdentifier.data; 5502 id = d2i_ASN1_OCTET_STRING(NULL, &p, 5503 (int)krb5_trusted_certifiers[i]->subjectKeyIdentifier.length); 5504 if (id == NULL) 5505 goto cleanup; 5506 /* XXX */ 5507 ASN1_OCTET_STRING_free(id); 5508 } 5509 i++; 5510 } 5511 /* XXX Since we not doing anything with received trusted certifiers 5512 * return an error. this is the place where we can pick a different 5513 * client certificate based on the information in td_trusted_certifiers 5514 */ 5515 retval = KRB5KDC_ERR_PREAUTH_FAILED; 5516 cleanup: 5517 if (sk_xn != NULL) 5518 sk_X509_NAME_pop_free(sk_xn, X509_NAME_free); 5519 5520 return retval; 5521 } 5522 5523 #ifdef DEBUG_DH 5524 static void 5525 print_dh(DH * dh, char *msg) 5526 { 5527 BIO *bio_err = NULL; 5528 5529 bio_err = BIO_new(BIO_s_file()); 5530 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 5531 5532 if (msg) 5533 BIO_puts(bio_err, (const char *)msg); 5534 if (dh) 5535 DHparams_print(bio_err, dh); 5536 5537 BIO_puts(bio_err, "private key: "); 5538 BN_print(bio_err, dh->priv_key); 5539 BIO_puts(bio_err, (const char *)"\n"); 5540 BIO_free(bio_err); 5541 5542 } 5543 5544 static void 5545 print_pubkey(BIGNUM * key, char *msg) 5546 { 5547 BIO *bio_err = NULL; 5548 5549 bio_err = BIO_new(BIO_s_file()); 5550 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 5551 5552 if (msg) 5553 BIO_puts(bio_err, (const char *)msg); 5554 if (key) 5555 BN_print(bio_err, key); 5556 BIO_puts(bio_err, "\n"); 5557 5558 BIO_free(bio_err); 5559 5560 } 5561 #endif 5562 5563 #ifndef WITHOUT_PKCS11 5564 static krb5_error_code 5565 p11err(krb5_context context, CK_RV rv, const char *op) 5566 { 5567 krb5_error_code code = KRB5KDC_ERR_PREAUTH_FAILED; 5568 size_t i; 5569 const char *msg; 5570 5571 for (i = 0; pkcs11_errstrings[i].text != NULL; i++) { 5572 if (pkcs11_errstrings[i].code == rv) 5573 break; 5574 } 5575 msg = pkcs11_errstrings[i].text; 5576 if (msg == NULL) 5577 msg = "unknown PKCS11 error"; 5578 5579 krb5_set_error_message(context, code, _("PKCS11 error (%s): %s"), op, msg); 5580 return code; 5581 } 5582 #endif 5583 5584 /* 5585 * Add an item to the pkinit_identity_crypto_context's list of deferred 5586 * identities. 5587 */ 5588 krb5_error_code 5589 crypto_set_deferred_id(krb5_context context, 5590 pkinit_identity_crypto_context id_cryptoctx, 5591 const char *identity, const char *password) 5592 { 5593 unsigned long ck_flags; 5594 5595 ck_flags = pkinit_get_deferred_id_flags(id_cryptoctx->deferred_ids, 5596 identity); 5597 return pkinit_set_deferred_id(&id_cryptoctx->deferred_ids, 5598 identity, ck_flags, password); 5599 } 5600 5601 /* 5602 * Retrieve a read-only copy of the pkinit_identity_crypto_context's list of 5603 * deferred identities, sure to be valid only until the next time someone calls 5604 * either pkinit_set_deferred_id() or crypto_set_deferred_id(). 5605 */ 5606 const pkinit_deferred_id * 5607 crypto_get_deferred_ids(krb5_context context, 5608 pkinit_identity_crypto_context id_cryptoctx) 5609 { 5610 pkinit_deferred_id *deferred; 5611 const pkinit_deferred_id *ret; 5612 5613 deferred = id_cryptoctx->deferred_ids; 5614 ret = (const pkinit_deferred_id *)deferred; 5615 return ret; 5616 } 5617 5618 /* Return the received certificate as DER-encoded data. */ 5619 krb5_error_code 5620 crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, 5621 uint8_t **der_out, size_t *der_len) 5622 { 5623 int len; 5624 unsigned char *der, *p; 5625 5626 *der_out = NULL; 5627 *der_len = 0; 5628 5629 if (reqctx->received_cert == NULL) 5630 return EINVAL; 5631 p = NULL; 5632 len = i2d_X509(reqctx->received_cert, NULL); 5633 if (len <= 0) 5634 return EINVAL; 5635 p = der = malloc(len); 5636 if (der == NULL) 5637 return ENOMEM; 5638 if (i2d_X509(reqctx->received_cert, &p) <= 0) { 5639 free(der); 5640 return EINVAL; 5641 } 5642 *der_out = der; 5643 *der_len = len; 5644 return 0; 5645 } 5646 5647 /* 5648 * Get the certificate matching data from the request certificate. 5649 */ 5650 krb5_error_code 5651 crypto_req_cert_matching_data(krb5_context context, 5652 pkinit_plg_crypto_context plgctx, 5653 pkinit_req_crypto_context reqctx, 5654 pkinit_cert_matching_data **md_out) 5655 { 5656 *md_out = NULL; 5657 5658 if (reqctx == NULL || reqctx->received_cert == NULL) 5659 return ENOENT; 5660 5661 return get_matching_data(context, plgctx, reqctx, reqctx->received_cert, 5662 md_out); 5663 } 5664 5665 /* 5666 * Historically, the strength of PKINIT key exchange has been determined by the 5667 * pkinit_dh_min_bits variable, which gives a finite field size. With the 5668 * addition of ECDH support, we allow the string values P-256, P-384, and P-521 5669 * for this config variable, represented with the rough equivalent bit 5670 * strengths for finite fields. 5671 */ 5672 int 5673 parse_dh_min_bits(krb5_context context, const char *str) 5674 { 5675 char *endptr; 5676 long n; 5677 5678 if (str == NULL) 5679 return PKINIT_DEFAULT_DH_MIN_BITS; 5680 5681 n = strtol(str, &endptr, 0); 5682 if (endptr == str) { 5683 if (strcasecmp(str, "P-256") == 0) 5684 return PKINIT_DH_P256_BITS; 5685 else if (strcasecmp(str, "P-384") == 0) 5686 return PKINIT_DH_P384_BITS; 5687 else if (strcasecmp(str, "P-521") == 0) 5688 return PKINIT_DH_P521_BITS; 5689 } else { 5690 if (n == 1024) 5691 return 1024; 5692 else if (n > 1024 && n <= 2048) 5693 return 2048; 5694 else if (n > 2048 && n <= 4096) 5695 return 4096; 5696 } 5697 5698 TRACE_PKINIT_DH_INVALID_MIN_BITS(context, str); 5699 return PKINIT_DEFAULT_DH_MIN_BITS; 5700 } 5701 5702 /* Return the OpenSSL message digest type matching the given CMS OID, or NULL 5703 * if it doesn't match any of the CMS OIDs we know about. */ 5704 static const EVP_MD * 5705 md_from_cms_oid(const krb5_data *alg_id) 5706 { 5707 if (data_eq(*alg_id, cms_sha1_id)) 5708 return EVP_sha1(); 5709 if (data_eq(*alg_id, cms_sha256_id)) 5710 return EVP_sha256(); 5711 if (data_eq(*alg_id, cms_sha384_id)) 5712 return EVP_sha384(); 5713 if (data_eq(*alg_id, cms_sha512_id)) 5714 return EVP_sha512(); 5715 return NULL; 5716 } 5717 5718 /* Compute a message digest of the given type over body, placing the result in 5719 * *digest_out in allocated storage. Return true on success. */ 5720 static krb5_boolean 5721 make_digest(const krb5_data *body, const EVP_MD *md, krb5_data *digest_out) 5722 { 5723 krb5_error_code ret; 5724 krb5_data d; 5725 5726 if (md == NULL) 5727 return FALSE; 5728 ret = alloc_data(&d, EVP_MD_size(md)); 5729 if (ret) 5730 return FALSE; 5731 if (!EVP_Digest(body->data, body->length, (uint8_t *)d.data, &d.length, md, 5732 NULL)) { 5733 free(d.data); 5734 return FALSE; 5735 } 5736 *digest_out = d; 5737 return TRUE; 5738 } 5739 5740 /* Return true if digest verifies for the given body and message digest 5741 * type. */ 5742 static krb5_boolean 5743 check_digest(const krb5_data *body, const EVP_MD *md, const krb5_data *digest) 5744 { 5745 unsigned int digest_len; 5746 uint8_t buf[EVP_MAX_MD_SIZE]; 5747 5748 if (md == NULL) 5749 return FALSE; 5750 if (!EVP_Digest(body->data, body->length, buf, &digest_len, md, NULL)) 5751 return FALSE; 5752 return (digest->length == digest_len && 5753 CRYPTO_memcmp(digest->data, buf, digest_len) == 0); 5754 } 5755 5756 krb5_error_code 5757 crypto_generate_checksums(krb5_context context, const krb5_data *body, 5758 krb5_data *cksum1_out, krb5_pachecksum2 **cksum2_out) 5759 { 5760 krb5_data cksum1 = empty_data(); 5761 krb5_pachecksum2 *cksum2 = NULL; 5762 krb5_error_code ret; 5763 5764 if (!make_digest(body, EVP_sha1(), &cksum1)) 5765 goto fail; 5766 5767 cksum2 = k5alloc(sizeof(*cksum2), &ret); 5768 if (cksum2 == NULL) 5769 goto fail; 5770 5771 if (!make_digest(body, EVP_sha256(), &cksum2->checksum)) 5772 goto fail; 5773 5774 if (krb5int_copy_data_contents(context, &cms_sha256_id, 5775 &cksum2->algorithmIdentifier.algorithm)) 5776 goto fail; 5777 5778 cksum2->algorithmIdentifier.parameters = empty_data(); 5779 5780 *cksum1_out = cksum1; 5781 *cksum2_out = cksum2; 5782 return 0; 5783 5784 fail: 5785 krb5_free_data_contents(context, &cksum1); 5786 free_pachecksum2(context, &cksum2); 5787 return KRB5_CRYPTO_INTERNAL; 5788 } 5789 5790 krb5_error_code 5791 crypto_verify_checksums(krb5_context context, krb5_data *body, 5792 const krb5_data *cksum1, 5793 const krb5_pachecksum2 *cksum2) 5794 { 5795 const EVP_MD *md; 5796 5797 /* RFC 4556 doesn't say what error to return if the checksum doesn't match. 5798 * Windows returns this one. */ 5799 if (!check_digest(body, EVP_sha1(), cksum1)) 5800 return KRB5KRB_AP_ERR_MODIFIED; 5801 5802 if (cksum2 == NULL) 5803 return 0; 5804 5805 md = md_from_cms_oid(&cksum2->algorithmIdentifier.algorithm); 5806 if (!check_digest(body, md, &cksum2->checksum)) 5807 return KRB5KRB_AP_ERR_MODIFIED; 5808 5809 return 0; 5810 } 5811 5812 #ifdef _WIN32 5813 BOOL WINAPI 5814 DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpvReserved) 5815 { 5816 if (fdwReason == DLL_PROCESS_ATTACH) 5817 pkinit_openssl_init__auxinit(); 5818 return TRUE; 5819 } 5820 #endif /* _WIN32 */ 5821