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