Print this page
8982 Support building with OpenSSL 1.1

*** 29,38 **** --- 29,39 ---- */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #include <errno.h> #include <string.h> #include <stdio.h>
*** 367,376 **** --- 368,472 ---- 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + #if OPENSSL_VERSION_NUMBER < 0x10100000L + /* + * Many things have changed in OpenSSL 1.1. The code in this file has been + * updated to use the v1.1 APIs but some are new and require emulation + * for older OpenSSL versions. + */ + + /* EVP_MD_CTX construct and destructor names have changed */ + + #define EVP_MD_CTX_new EVP_MD_CTX_create + #define EVP_MD_CTX_free EVP_MD_CTX_destroy + + /* ASN1_STRING_data is deprecated */ + #define ASN1_STRING_get0_data ASN1_STRING_data + + /* X509_STORE_CTX_trusted_stack is deprecated */ + #define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack + + /* get_rfc2409_prime_1024() has been renamed. */ + #define BN_get_rfc2409_prime_1024 get_rfc2409_prime_1024 + + #define OBJ_get0_data(o) ((o)->data) + #define OBJ_length(o) ((o)->length) + + /* Some new DH functions that aren't in OpenSSL 1.0.x */ + #define DH_bits(dh) BN_num_bits((dh)->p); + + #define DH_set0_pqg(dh, p, q, g) __DH_set0_pqg(dh, p, q, g) + static int + __DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) + { + if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return 1; + } + + #define DH_get0_pqg(dh, p, q, g) __DH_get0_pqg(dh, p, q, g) + static void + __DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, + const BIGNUM **g) + { + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; + } + + #define DH_set0_key(dh, pub, priv) __DH_set0_key(dh, pub, priv) + static int + __DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) + { + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return 1; + } + + #define DH_get0_key(dh, pub, priv) __DH_get0_key(dh, pub, priv) + static void + __DH_get0_key(const DH *dh, const BIGNUM **pub, const BIGNUM **priv) + { + if (pub != NULL) + *pub = dh->pub_key; + if (priv != NULL) + *priv = dh->priv_key; + } + + #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + /* Solaris Kerberos */ static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER; static int pkinit_oids_refs = 0; krb5_error_code
*** 654,705 **** return; /* Only call OBJ_cleanup once! */ /* Solaris Kerberos: locking */ k5_mutex_lock(&oids_mutex); if (--pkinit_oids_refs == 0) OBJ_cleanup(); k5_mutex_unlock(&oids_mutex); } static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) { krb5_error_code retval = ENOMEM; ! plgctx->dh_1024 = DH_new(); if (plgctx->dh_1024 == NULL) goto cleanup; - plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime, - sizeof(pkinit_1024_dhprime), NULL); - if ((plgctx->dh_1024->g = BN_new()) == NULL || - (plgctx->dh_1024->q = BN_new()) == NULL) - goto cleanup; - BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2); - BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p); ! plgctx->dh_2048 = DH_new(); if (plgctx->dh_2048 == NULL) goto cleanup; - plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime, - sizeof(pkinit_2048_dhprime), NULL); - if ((plgctx->dh_2048->g = BN_new()) == NULL || - (plgctx->dh_2048->q = BN_new()) == NULL) - goto cleanup; - BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2); - BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p); ! plgctx->dh_4096 = DH_new(); if (plgctx->dh_4096 == NULL) goto cleanup; - plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime, - sizeof(pkinit_4096_dhprime), NULL); - if ((plgctx->dh_4096->g = BN_new()) == NULL || - (plgctx->dh_4096->q = BN_new()) == NULL) - goto cleanup; - BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2); - BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p); retval = 0; cleanup: if (retval) --- 750,823 ---- return; /* Only call OBJ_cleanup once! */ /* Solaris Kerberos: locking */ k5_mutex_lock(&oids_mutex); + #if OPENSSL_VERSION_NUMBER < 0x10100000L + /* + * In OpenSSL versions prior to 1.1.0, OBJ_cleanup() cleaned up OpenSSL's + * internal object table. This function is deprecated in version 1.1.0. + * No explicit de-initialisation is now required. + */ if (--pkinit_oids_refs == 0) OBJ_cleanup(); + #else + pkinit_oids_refs--; + #endif k5_mutex_unlock(&oids_mutex); } + /* Construct an OpenSSL DH object for an Oakley group. */ + static DH * + make_dhprime(uint8_t *prime, size_t len) + { + DH *dh = NULL; + BIGNUM *p = NULL, *q = NULL, *g = NULL; + + if ((p = BN_bin2bn(prime, len, NULL)) == NULL) + goto cleanup; + if ((q = BN_new()) == NULL) + goto cleanup; + if (!BN_rshift1(q, p)) + goto cleanup; + if ((g = BN_new()) == NULL) + goto cleanup; + if (!BN_set_word(g, DH_GENERATOR_2)) + goto cleanup; + + dh = DH_new(); + if (dh == NULL) + goto cleanup; + DH_set0_pqg(dh, p, q, g); + p = g = q = NULL; + + cleanup: + BN_free(p); + BN_free(q); + BN_free(g); + return dh; + } + static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) { krb5_error_code retval = ENOMEM; ! plgctx->dh_1024 = make_dhprime(pkinit_1024_dhprime, ! sizeof(pkinit_1024_dhprime)); if (plgctx->dh_1024 == NULL) goto cleanup; ! plgctx->dh_2048 = make_dhprime(pkinit_2048_dhprime, ! sizeof(pkinit_2048_dhprime)); if (plgctx->dh_2048 == NULL) goto cleanup; ! plgctx->dh_4096 = make_dhprime(pkinit_4096_dhprime, ! sizeof(pkinit_4096_dhprime)); if (plgctx->dh_4096 == NULL) goto cleanup; retval = 0; cleanup: if (retval)
*** 856,866 **** PKCS7_SIGNER_INFO *p7si = NULL; unsigned char *p; ASN1_TYPE *pkinit_data = NULL; STACK_OF(X509) * cert_stack = NULL; ASN1_OCTET_STRING *digest_attr = NULL; ! EVP_MD_CTX ctx, ctx2; const EVP_MD *md_tmp = NULL; unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE]; unsigned char *digestInfo_buf = NULL, *abuf = NULL; unsigned int md_len, md_len2, alen, digestInfo_len; STACK_OF(X509_ATTRIBUTE) * sk; --- 974,984 ---- PKCS7_SIGNER_INFO *p7si = NULL; unsigned char *p; ASN1_TYPE *pkinit_data = NULL; STACK_OF(X509) * cert_stack = NULL; ASN1_OCTET_STRING *digest_attr = NULL; ! EVP_MD_CTX *ctx = NULL, *ctx2 = NULL; const EVP_MD *md_tmp = NULL; unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE]; unsigned char *digestInfo_buf = NULL, *abuf = NULL; unsigned int md_len, md_len2, alen, digestInfo_len; STACK_OF(X509_ATTRIBUTE) * sk;
*** 900,939 **** pkiDebug("only including signer's certificate\n"); sk_X509_push(cert_stack, X509_dup(cert)); } else { /* create a cert chain */ X509_STORE *certstore = NULL; ! X509_STORE_CTX certctx; STACK_OF(X509) *certstack = NULL; char buf[DN_BUF_LEN]; int i = 0, size = 0; if ((certstore = X509_STORE_new()) == NULL) goto cleanup; pkiDebug("building certificate chain\n"); ! X509_STORE_set_verify_cb_func(certstore, openssl_callback); ! X509_STORE_CTX_init(&certctx, certstore, cert, id_cryptoctx->intermediateCAs); ! X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs); /* Solaris Kerberos */ ! if (X509_verify_cert(&certctx) <= 0) { pkiDebug("failed to create a certificate chain: %s\n", ! X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx))); if (!sk_X509_num(id_cryptoctx->trustedCAs)) pkiDebug("No trusted CAs found. Check your X509_anchors\n"); goto cleanup; } ! certstack = X509_STORE_CTX_get1_chain(&certctx); size = sk_X509_num(certstack); pkiDebug("size of certificate chain = %d\n", size); for(i = 0; i < size - 1; i++) { X509 *x = sk_X509_value(certstack, i); X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf)); pkiDebug("cert #%d: %s\n", i, buf); sk_X509_push(cert_stack, X509_dup(x)); } ! X509_STORE_CTX_cleanup(&certctx); X509_STORE_free(certstore); sk_X509_pop_free(certstack, X509_free); } p7s->cert = cert_stack; --- 1018,1059 ---- pkiDebug("only including signer's certificate\n"); sk_X509_push(cert_stack, X509_dup(cert)); } else { /* create a cert chain */ X509_STORE *certstore = NULL; ! X509_STORE_CTX *certctx; STACK_OF(X509) *certstack = NULL; char buf[DN_BUF_LEN]; int i = 0, size = 0; if ((certstore = X509_STORE_new()) == NULL) goto cleanup; + if ((certctx = X509_STORE_CTX_new()) == NULL) + goto cleanup; pkiDebug("building certificate chain\n"); ! X509_STORE_set_verify_cb(certstore, openssl_callback); ! X509_STORE_CTX_init(certctx, certstore, cert, id_cryptoctx->intermediateCAs); ! X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs); /* Solaris Kerberos */ ! if (X509_verify_cert(certctx) <= 0) { pkiDebug("failed to create a certificate chain: %s\n", ! X509_verify_cert_error_string(X509_STORE_CTX_get_error(certctx))); if (!sk_X509_num(id_cryptoctx->trustedCAs)) pkiDebug("No trusted CAs found. Check your X509_anchors\n"); goto cleanup; } ! certstack = X509_STORE_CTX_get1_chain(certctx); size = sk_X509_num(certstack); pkiDebug("size of certificate chain = %d\n", size); for(i = 0; i < size - 1; i++) { X509 *x = sk_X509_value(certstack, i); X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf)); pkiDebug("cert #%d: %s\n", i, buf); sk_X509_push(cert_stack, X509_dup(x)); } ! X509_STORE_CTX_free(certctx); X509_STORE_free(certstore); sk_X509_pop_free(certstack, X509_free); } p7s->cert = cert_stack;
*** 945,957 **** if (!X509_NAME_set(&p7si->issuer_and_serial->issuer, X509_get_issuer_name(cert))) goto cleanup; /* because ASN1_INTEGER_set is used to set a 'long' we will do * things the ugly way. */ ! M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial); if (!(p7si->issuer_and_serial->serial = ! M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) goto cleanup; /* will not fill-out EVP_PKEY because it's on the smartcard */ /* Set digest algs */ --- 1065,1077 ---- if (!X509_NAME_set(&p7si->issuer_and_serial->issuer, X509_get_issuer_name(cert))) goto cleanup; /* because ASN1_INTEGER_set is used to set a 'long' we will do * things the ugly way. */ ! ASN1_INTEGER_free(p7si->issuer_and_serial->serial); if (!(p7si->issuer_and_serial->serial = ! ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) goto cleanup; /* will not fill-out EVP_PKEY because it's on the smartcard */ /* Set digest algs */
*** 981,995 **** abuf = data; alen = data_len; } else { /* add signed attributes */ /* compute sha1 digest over the EncapsulatedContentInfo */ ! EVP_MD_CTX_init(&ctx); ! EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); ! EVP_DigestUpdate(&ctx, data, data_len); ! md_tmp = EVP_MD_CTX_md(&ctx); ! EVP_DigestFinal_ex(&ctx, md_data, &md_len); /* create a message digest attr */ digest_attr = ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len); PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest, --- 1101,1120 ---- abuf = data; alen = data_len; } else { /* add signed attributes */ /* compute sha1 digest over the EncapsulatedContentInfo */ ! ctx = EVP_MD_CTX_new(); ! if (ctx == NULL) ! goto cleanup2; ! EVP_MD_CTX_init(ctx); ! EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); ! EVP_DigestUpdate(ctx, data, data_len); ! md_tmp = EVP_MD_CTX_md(ctx); ! EVP_DigestFinal_ex(ctx, md_data, &md_len); ! EVP_MD_CTX_free(ctx); ! ctx = NULL; /* create a message digest attr */ digest_attr = ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len); PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
*** 1017,1034 **** * digest OCTET STRING } */ if (id_cryptoctx->pkcs11_method == 1 && id_cryptoctx->mech == CKM_RSA_PKCS) { pkiDebug("mech = CKM_RSA_PKCS\n"); ! EVP_MD_CTX_init(&ctx2); /* if this is not draft9 request, include digest signed attribute */ if (cms_msg_type != CMS_SIGN_DRAFT9) ! EVP_DigestInit_ex(&ctx2, md_tmp, NULL); else ! EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL); ! EVP_DigestUpdate(&ctx2, abuf, alen); ! EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2); alg = X509_ALGOR_new(); if (alg == NULL) goto cleanup2; alg->algorithm = OBJ_nid2obj(NID_sha1); --- 1142,1164 ---- * digest OCTET STRING } */ if (id_cryptoctx->pkcs11_method == 1 && id_cryptoctx->mech == CKM_RSA_PKCS) { pkiDebug("mech = CKM_RSA_PKCS\n"); ! ctx2 = EVP_MD_CTX_new(); ! if (ctx2 == NULL) ! goto cleanup2; ! EVP_MD_CTX_init(ctx2); /* if this is not draft9 request, include digest signed attribute */ if (cms_msg_type != CMS_SIGN_DRAFT9) ! EVP_DigestInit_ex(ctx2, md_tmp, NULL); else ! EVP_DigestInit_ex(ctx2, EVP_sha1(), NULL); ! EVP_DigestUpdate(ctx2, abuf, alen); ! EVP_DigestFinal_ex(ctx2, md_data2, &md_len2); ! EVP_MD_CTX_free(ctx2); ! ctx2 = NULL; alg = X509_ALGOR_new(); if (alg == NULL) goto cleanup2; alg->algorithm = OBJ_nid2obj(NID_sha1);
*** 1158,1172 **** } #endif cleanup2: if (cms_msg_type != CMS_SIGN_DRAFT9) ! EVP_MD_CTX_cleanup(&ctx); #ifndef WITHOUT_PKCS11 if (id_cryptoctx->pkcs11_method == 1 && id_cryptoctx->mech == CKM_RSA_PKCS) { ! EVP_MD_CTX_cleanup(&ctx2); if (digest_buf != NULL) free(digest_buf); if (digestInfo_buf != NULL) free(digestInfo_buf); if (alg_buf != NULL) --- 1288,1304 ---- } #endif cleanup2: if (cms_msg_type != CMS_SIGN_DRAFT9) ! if (ctx != NULL) ! EVP_MD_CTX_free(ctx); #ifndef WITHOUT_PKCS11 if (id_cryptoctx->pkcs11_method == 1 && id_cryptoctx->mech == CKM_RSA_PKCS) { ! if (ctx2 != NULL) ! EVP_MD_CTX_free(ctx2); if (digest_buf != NULL) free(digest_buf); if (digestInfo_buf != NULL) free(digestInfo_buf); if (alg_buf != NULL)
*** 1208,1218 **** const unsigned char *p = signed_data; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; PKCS7_SIGNER_INFO *si = NULL; X509 *x = NULL; X509_STORE *store = NULL; ! X509_STORE_CTX cert_ctx; STACK_OF(X509) *intermediateCAs = NULL; STACK_OF(X509_CRL) *revoked = NULL; STACK_OF(X509) *verified_chain = NULL; ASN1_OBJECT *oid = NULL; krb5_external_principal_identifier **krb5_verified_chain = NULL; --- 1340,1350 ---- const unsigned char *p = signed_data; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; PKCS7_SIGNER_INFO *si = NULL; X509 *x = NULL; X509_STORE *store = NULL; ! X509_STORE_CTX *cert_ctx; STACK_OF(X509) *intermediateCAs = NULL; STACK_OF(X509_CRL) *revoked = NULL; STACK_OF(X509) *verified_chain = NULL; ASN1_OBJECT *oid = NULL; krb5_external_principal_identifier **krb5_verified_chain = NULL;
*** 1252,1264 **** goto cleanup; /* check if we are inforcing CRL checking */ vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; if (require_crl_checking) ! X509_STORE_set_verify_cb_func(store, openssl_callback); else ! X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls); X509_STORE_set_flags(store, vflags); /* get the signer's information from the PKCS7 message */ if ((si_sk = PKCS7_get_signer_info(p7)) == NULL) goto cleanup; --- 1384,1396 ---- goto cleanup; /* check if we are inforcing CRL checking */ vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; if (require_crl_checking) ! X509_STORE_set_verify_cb(store, openssl_callback); else ! X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls); X509_STORE_set_flags(store, vflags); /* get the signer's information from the PKCS7 message */ if ((si_sk = PKCS7_get_signer_info(p7)) == NULL) goto cleanup;
*** 1305,1322 **** } /* initialize x509 context with the received certificate and * trusted and intermediate CA chains and CRLs */ ! if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs)) goto cleanup; ! X509_STORE_CTX_set0_crls(&cert_ctx, revoked); /* add trusted CAs certificates for cert verification */ if (idctx->trustedCAs != NULL) ! X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs); else { pkiDebug("unable to find any trusted CAs\n"); goto cleanup; } #ifdef DEBUG_CERTCHAIN --- 1437,1456 ---- } /* initialize x509 context with the received certificate and * trusted and intermediate CA chains and CRLs */ ! if ((cert_ctx = X509_STORE_CTX_new()) == NULL) goto cleanup; + if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs)) + goto cleanup; ! X509_STORE_CTX_set0_crls(cert_ctx, revoked); /* add trusted CAs certificates for cert verification */ if (idctx->trustedCAs != NULL) ! X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs); else { pkiDebug("unable to find any trusted CAs\n"); goto cleanup; } #ifdef DEBUG_CERTCHAIN
*** 1347,1361 **** pkiDebug("crls by CA #%d: %s\n", i , buf); } } #endif ! i = X509_verify_cert(&cert_ctx); if (i <= 0) { ! int j = X509_STORE_CTX_get_error(&cert_ctx); ! reqctx->received_cert = X509_dup(cert_ctx.current_cert); switch(j) { case X509_V_ERR_CERT_REVOKED: retval = KRB5KDC_ERR_REVOKED_CERTIFICATE; break; case X509_V_ERR_UNABLE_TO_GET_CRL: --- 1481,1496 ---- pkiDebug("crls by CA #%d: %s\n", i , buf); } } #endif ! i = X509_verify_cert(cert_ctx); if (i <= 0) { ! int j = X509_STORE_CTX_get_error(cert_ctx); ! reqctx->received_cert = X509_dup( ! X509_STORE_CTX_get_current_cert(cert_ctx)); switch(j) { case X509_V_ERR_CERT_REVOKED: retval = KRB5KDC_ERR_REVOKED_CERTIFICATE; break; case X509_V_ERR_UNABLE_TO_GET_CRL:
*** 1384,1396 **** } #endif } else { /* retrieve verified certificate chain */ if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) ! verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx); } ! X509_STORE_CTX_cleanup(&cert_ctx); if (i <= 0) goto cleanup; out = BIO_new(BIO_s_mem()); if (cms_msg_type == CMS_SIGN_DRAFT9) --- 1519,1531 ---- } #endif } else { /* retrieve verified certificate chain */ if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) ! verified_chain = X509_STORE_CTX_get1_chain(cert_ctx); } ! X509_STORE_CTX_free(cert_ctx); if (i <= 0) goto cleanup; out = BIO_new(BIO_s_mem()); if (cms_msg_type == CMS_SIGN_DRAFT9)
*** 1417,1429 **** } if (valid_oid) pkiDebug("PKCS7 Verification successful\n"); else { pkiDebug("wrong oid in eContentType\n"); ! print_buffer((unsigned char *)p7->d.sign->contents->type->data, ! (unsigned int)p7->d.sign->contents->type->length); retval = KRB5KDC_ERR_PREAUTH_FAILED; krb5_set_error_message(context, retval, "wrong oid\n"); goto cleanup; } } --- 1552,1565 ---- } if (valid_oid) pkiDebug("PKCS7 Verification successful\n"); else { + const ASN1_OBJECT *etype = p7->d.sign->contents->type; pkiDebug("wrong oid in eContentType\n"); ! print_buffer((unsigned char *)OBJ_get0_data(etype), ! OBJ_length(etype)); retval = KRB5KDC_ERR_PREAUTH_FAILED; krb5_set_error_message(context, retval, "wrong oid\n"); goto cleanup; } }
*** 2161,2203 **** unsigned int *dh_pubkey_len) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; unsigned char *buf = NULL; int dh_err = 0; ! ASN1_INTEGER *pub_key = NULL; if (cryptoctx->dh == NULL) { if ((cryptoctx->dh = DH_new()) == NULL) goto cleanup; ! if ((cryptoctx->dh->g = BN_new()) == NULL || ! (cryptoctx->dh->q = BN_new()) == NULL) goto cleanup; switch(dh_size) { case 1024: pkiDebug("client uses 1024 DH keys\n"); ! cryptoctx->dh->p = get_rfc2409_prime_1024(NULL); break; case 2048: pkiDebug("client uses 2048 DH keys\n"); ! cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime, ! sizeof(pkinit_2048_dhprime), NULL); break; case 4096: pkiDebug("client uses 4096 DH keys\n"); ! cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime, ! sizeof(pkinit_4096_dhprime), NULL); break; ! default: goto cleanup; } - BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2); - BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p); - } - DH_generate_key(cryptoctx->dh); /* Solaris Kerberos */ #ifdef DEBUG DH_check(cryptoctx->dh, &dh_err); if (dh_err != 0) { pkiDebug("Warning: dh_check failed with %d\n", dh_err); --- 2297,2340 ---- unsigned int *dh_pubkey_len) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; unsigned char *buf = NULL; int dh_err = 0; ! ASN1_INTEGER *asn_pub_key = NULL; ! BIGNUM *p, *g, *q; ! const BIGNUM *pub_key; if (cryptoctx->dh == NULL) { if ((cryptoctx->dh = DH_new()) == NULL) goto cleanup; ! if ((g = BN_new()) == NULL || (q = BN_new()) == NULL) goto cleanup; switch(dh_size) { case 1024: pkiDebug("client uses 1024 DH keys\n"); ! cryptoctx->dh = make_dhprime(pkinit_1024_dhprime, ! sizeof(pkinit_1024_dhprime)); break; case 2048: pkiDebug("client uses 2048 DH keys\n"); ! cryptoctx->dh = make_dhprime(pkinit_2048_dhprime, ! sizeof(pkinit_2048_dhprime)); break; case 4096: pkiDebug("client uses 4096 DH keys\n"); ! cryptoctx->dh = make_dhprime(pkinit_4096_dhprime, ! sizeof(pkinit_4096_dhprime)); break; ! } ! if (cryptoctx->dh == NULL) goto cleanup; } DH_generate_key(cryptoctx->dh); + DH_get0_key(cryptoctx->dh, &pub_key, NULL); + /* Solaris Kerberos */ #ifdef DEBUG DH_check(cryptoctx->dh, &dh_err); if (dh_err != 0) { pkiDebug("Warning: dh_check failed with %d\n", dh_err);
*** 2211,2256 **** pkiDebug("the g value is not a generator\n"); } #endif #ifdef DEBUG_DH print_dh(cryptoctx->dh, "client's DH params\n"); ! print_pubkey(cryptoctx->dh->pub_key, "client's pub_key="); #endif ! DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err); if (dh_err != 0) { pkiDebug("dh_check_pub_key failed with %d\n", dh_err); goto cleanup; } /* pack DHparams */ /* aglo: usually we could just call i2d_DHparams to encode DH params * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3. */ ! retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g, ! cryptoctx->dh->q, dh_params, dh_params_len); if (retval) goto cleanup; /* pack DH public key */ /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this * encoding shall be used as the contents (the value) of the * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo * data element */ ! if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL) goto cleanup; ! *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL); if ((buf = *dh_pubkey = (unsigned char *) malloc((size_t) *dh_pubkey_len)) == NULL) { retval = ENOMEM; goto cleanup; } ! i2d_ASN1_INTEGER(pub_key, &buf); ! if (pub_key != NULL) ! ASN1_INTEGER_free(pub_key); retval = 0; return retval; cleanup: --- 2348,2394 ---- pkiDebug("the g value is not a generator\n"); } #endif #ifdef DEBUG_DH print_dh(cryptoctx->dh, "client's DH params\n"); ! print_pubkey(pub_key, "client's pub_key="); #endif ! DH_check_pub_key(cryptoctx->dh, pub_key, &dh_err); if (dh_err != 0) { pkiDebug("dh_check_pub_key failed with %d\n", dh_err); goto cleanup; } /* pack DHparams */ /* aglo: usually we could just call i2d_DHparams to encode DH params * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3. */ ! DH_get0_pqg(cryptoctx->dh, (const BIGNUM **)&p, (const BIGNUM **)&q, ! (const BIGNUM **)&g); ! retval = pkinit_encode_dh_params(p, g, q, dh_params, dh_params_len); if (retval) goto cleanup; /* pack DH public key */ /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this * encoding shall be used as the contents (the value) of the * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo * data element */ ! if ((asn_pub_key = BN_to_ASN1_INTEGER(pub_key, NULL)) == NULL) goto cleanup; ! *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL); if ((buf = *dh_pubkey = (unsigned char *) malloc((size_t) *dh_pubkey_len)) == NULL) { retval = ENOMEM; goto cleanup; } ! i2d_ASN1_INTEGER(asn_pub_key, &buf); ! if (asn_pub_key != NULL) ! ASN1_INTEGER_free(asn_pub_key); retval = 0; return retval; cleanup:
*** 2261,2272 **** free(*dh_params); *dh_params = NULL; if (*dh_pubkey != NULL) free(*dh_pubkey); *dh_pubkey = NULL; ! if (pub_key != NULL) ! ASN1_INTEGER_free(pub_key); return retval; } /* ARGSUSED */ --- 2399,2410 ---- free(*dh_params); *dh_params = NULL; if (*dh_pubkey != NULL) free(*dh_pubkey); *dh_pubkey = NULL; ! if (asn_pub_key != NULL) ! ASN1_INTEGER_free(asn_pub_key); return retval; } /* ARGSUSED */
*** 2350,2393 **** { DH *dh = NULL; unsigned char *tmp = NULL; int dh_prime_bits; krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; tmp = dh_params->data; dh = DH_new(); dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length); if (dh == NULL) { pkiDebug("failed to decode dhparams\n"); goto cleanup; } /* KDC SHOULD check to see if the key parameters satisfy its policy */ ! dh_prime_bits = BN_num_bits(dh->p); if (minbits && dh_prime_bits < minbits) { pkiDebug("client sent dh params with %d bits, we require %d\n", dh_prime_bits, minbits); goto cleanup; } /* check dhparams is group 2 */ ! if (pkinit_check_dh_params(cryptoctx->dh_1024->p, ! dh->p, dh->g, dh->q) == 0) { retval = 0; goto cleanup; } /* check dhparams is group 14 */ ! if (pkinit_check_dh_params(cryptoctx->dh_2048->p, ! dh->p, dh->g, dh->q) == 0) { retval = 0; goto cleanup; } /* check dhparams is group 16 */ ! if (pkinit_check_dh_params(cryptoctx->dh_4096->p, ! dh->p, dh->g, dh->q) == 0) { retval = 0; goto cleanup; } cleanup: --- 2488,2534 ---- { DH *dh = NULL; unsigned char *tmp = NULL; int dh_prime_bits; krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; + const BIGNUM *p, *g, *q, *p2; tmp = dh_params->data; dh = DH_new(); dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length); if (dh == NULL) { pkiDebug("failed to decode dhparams\n"); goto cleanup; } + DH_get0_pqg(dh, &p, &q, &g); + /* KDC SHOULD check to see if the key parameters satisfy its policy */ ! dh_prime_bits = BN_num_bits(p); if (minbits && dh_prime_bits < minbits) { pkiDebug("client sent dh params with %d bits, we require %d\n", dh_prime_bits, minbits); goto cleanup; } /* check dhparams is group 2 */ ! DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL); ! if (pkinit_check_dh_params(p2, p, g, q) == 0) { retval = 0; goto cleanup; } /* check dhparams is group 14 */ ! DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL); ! if (pkinit_check_dh_params(p2, p, g, q) == 0) { retval = 0; goto cleanup; } /* check dhparams is group 16 */ ! DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL); ! if (pkinit_check_dh_params(p2, p, g, q) == 0) { retval = 0; goto cleanup; } cleanup:
*** 2414,2459 **** unsigned int *server_key_len) { /* Solaris Kerberos */ krb5_error_code retval = KRB5KRB_ERR_GENERIC; DH *dh = NULL, *dh_server = NULL; ! unsigned char *p = NULL; ! ASN1_INTEGER *pub_key = NULL; /* get client's received DH parameters that we saved in server_check_dh */ dh = cryptoctx->dh; dh_server = DH_new(); if (dh_server == NULL) goto cleanup; ! dh_server->p = BN_dup(dh->p); ! dh_server->g = BN_dup(dh->g); ! dh_server->q = BN_dup(dh->q); /* decode client's public key */ ! p = data; ! pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len); if (pub_key == NULL) goto cleanup; ! dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL); ! if (dh->pub_key == NULL) ! goto cleanup; ! ASN1_INTEGER_free(pub_key); if (!DH_generate_key(dh_server)) goto cleanup; /* generate DH session key */ *server_key_len = DH_size(dh_server); ! if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL) goto cleanup; ! DH_compute_key(*server_key, dh->pub_key, dh_server); #ifdef DEBUG_DH print_dh(dh_server, "client&server's DH params\n"); ! print_pubkey(dh->pub_key, "client's pub_key="); ! print_pubkey(dh_server->pub_key, "server's pub_key="); pkiDebug("server secret key="); print_buffer(*server_key, *server_key_len); #endif /* KDC reply */ --- 2555,2605 ---- unsigned int *server_key_len) { /* Solaris Kerberos */ krb5_error_code retval = KRB5KRB_ERR_GENERIC; DH *dh = NULL, *dh_server = NULL; ! const BIGNUM *p, *g, *q, *s_pub_key; ! BIGNUM *pub_key; ! unsigned char *s = NULL; ! ASN1_INTEGER *asn_pub_key = NULL; /* get client's received DH parameters that we saved in server_check_dh */ dh = cryptoctx->dh; dh_server = DH_new(); if (dh_server == NULL) goto cleanup; ! DH_get0_pqg(dh, &p, &g, &q); ! DH_set0_pqg(dh_server, BN_dup(p), BN_dup(g), BN_dup(q)); /* decode client's public key */ ! s = data; ! asn_pub_key = d2i_ASN1_INTEGER(NULL, ! (const unsigned char **)&s, (int)data_len); ! if (asn_pub_key == NULL) ! goto cleanup; ! pub_key = ASN1_INTEGER_to_BN(asn_pub_key, NULL); if (pub_key == NULL) goto cleanup; ! DH_set0_key(dh, pub_key, NULL); ! ASN1_INTEGER_free(asn_pub_key); if (!DH_generate_key(dh_server)) goto cleanup; /* generate DH session key */ *server_key_len = DH_size(dh_server); ! if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) ! == NULL) goto cleanup; ! DH_compute_key(*server_key, pub_key, dh_server); ! DH_get0_key(dh_server, &s_pub_key, NULL); #ifdef DEBUG_DH print_dh(dh_server, "client&server's DH params\n"); ! print_pubkey(pub_key, "client's pub_key="); ! print_pubkey(s_pub_key, "server's pub_key="); pkiDebug("server secret key="); print_buffer(*server_key, *server_key_len); #endif /* KDC reply */
*** 2461,2478 **** /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this * encoding shall be used as the contents (the value) of the * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo * data element */ ! if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL) goto cleanup; ! *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL); ! if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL) goto cleanup; ! i2d_ASN1_INTEGER(pub_key, &p); ! if (pub_key != NULL) ! ASN1_INTEGER_free(pub_key); retval = 0; if (dh_server != NULL) DH_free(dh_server); --- 2607,2625 ---- /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this * encoding shall be used as the contents (the value) of the * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo * data element */ ! if ((asn_pub_key = BN_to_ASN1_INTEGER(s_pub_key, NULL)) == NULL) goto cleanup; ! *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL); ! if ((s = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) ! == NULL) goto cleanup; ! i2d_ASN1_INTEGER(asn_pub_key, &s); ! if (asn_pub_key != NULL) ! ASN1_INTEGER_free(asn_pub_key); retval = 0; if (dh_server != NULL) DH_free(dh_server);
*** 2502,2523 **** ret = k5_mutex_lock(&init_mutex); if (ret == 0) { if (!did_init) { /* initialize openssl routines */ CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); did_init++; } k5_mutex_unlock(&init_mutex); } return (ret); } static krb5_error_code ! pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q, unsigned char **buf, unsigned int *buf_len) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; int bufsize = 0, r = 0; unsigned char *tmp = NULL; --- 2649,2676 ---- ret = k5_mutex_lock(&init_mutex); if (ret == 0) { if (!did_init) { /* initialize openssl routines */ + #if OPENSSL_VERSION_NUMBER < 0x10100000L + /* + * As of version 1.1.0, OpenSSL will automatically allocate + * resources as-needed. + */ CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); + #endif did_init++; } k5_mutex_unlock(&init_mutex); } return (ret); } static krb5_error_code ! pkinit_encode_dh_params(const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, unsigned char **buf, unsigned int *buf_len) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; int bufsize = 0, r = 0; unsigned char *tmp = NULL;
*** 2558,2567 **** --- 2711,2722 ---- ASN1_INTEGER_free(aq); return retval; } + #if OPENSSL_VERSION_NUMBER < 0x10100000L + static DH * pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len) { ASN1_INTEGER ai, *aip = NULL; long length = (long) len;
*** 2617,2626 **** --- 2772,2838 ---- M_ASN1_D2I_end_sequence(); M_ASN1_D2I_Finish(a, DH_free, 0); } + #else + + /* + * This is taken from the internal dh_asn1.c file in OpenSSL 1.1, modified to + * make q an optional field. + */ + + typedef struct { + ASN1_BIT_STRING *seed; + BIGNUM *counter; + } int_dhvparams; + + typedef struct { + BIGNUM *p; + BIGNUM *q; + BIGNUM *g; + BIGNUM *j; + int_dhvparams *vparams; + } int_dhx942_dh; + + ASN1_SEQUENCE(DHvparams) = { + ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING), + ASN1_SIMPLE(int_dhvparams, counter, BIGNUM) + } static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams) + + ASN1_SEQUENCE(DHxparams) = { + ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM), + ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM), + ASN1_OPT(int_dhx942_dh, q, BIGNUM), + ASN1_OPT(int_dhx942_dh, j, BIGNUM), + ASN1_OPT(int_dhx942_dh, vparams, DHvparams), + } static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams) + + static DH * + pkinit_decode_dh_params(DH **a, unsigned char **pp, unsigned int len) + { + int_dhx942_dh *params; + DH *dh = *a; + + if (dh == NULL) + return NULL; + + params = (int_dhx942_dh *)ASN1_item_d2i(NULL, + (const unsigned char **)pp, len, ASN1_ITEM_rptr(DHxparams)); + if (params == NULL) { + DH_free(dh); + return NULL; + } + + DH_set0_pqg(dh, params->p, params->q, params->g); + params->p = params->q = params->g = NULL; + ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(DHxparams)); + return dh; + } + + #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + static krb5_error_code pkinit_create_sequence_of_principal_identifiers( krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, pkinit_req_crypto_context req_cryptoctx,
*** 2761,2794 **** unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0; unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL; krb5_typed_data **typed_data = NULL; krb5_data *data = NULL, *encoded_algId = NULL; krb5_algorithm_identifier **algId = NULL; /* Solaris Kerberos */ if (opts->dh_min_bits > 4096) { retval = EINVAL; goto cleanup; } if (opts->dh_min_bits <= 1024) { ! retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p, ! plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q, ! &buf1, &buf1_len); if (retval) goto cleanup; } if (opts->dh_min_bits <= 2048) { ! retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p, ! plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q, ! &buf2, &buf2_len); if (retval) goto cleanup; } ! retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p, ! plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q, ! &buf3, &buf3_len); if (retval) goto cleanup; if (opts->dh_min_bits <= 1024) { algId = malloc(4 * sizeof(krb5_algorithm_identifier *)); --- 2973,3004 ---- unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0; unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL; krb5_typed_data **typed_data = NULL; krb5_data *data = NULL, *encoded_algId = NULL; krb5_algorithm_identifier **algId = NULL; + const BIGNUM *p, *q, *g; /* Solaris Kerberos */ if (opts->dh_min_bits > 4096) { retval = EINVAL; goto cleanup; } if (opts->dh_min_bits <= 1024) { ! DH_get0_pqg(plg_cryptoctx->dh_1024, &p, &q, &g); ! retval = pkinit_encode_dh_params(p, g, q, &buf1, &buf1_len); if (retval) goto cleanup; } if (opts->dh_min_bits <= 2048) { ! DH_get0_pqg(plg_cryptoctx->dh_2048, &p, &q, &g); ! retval = pkinit_encode_dh_params(p, g, q, &buf2, &buf2_len); if (retval) goto cleanup; } ! DH_get0_pqg(plg_cryptoctx->dh_4096, &p, &q, &g); ! retval = pkinit_encode_dh_params(p, g, q, &buf3, &buf3_len); if (retval) goto cleanup; if (opts->dh_min_bits <= 1024) { algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
*** 2978,2988 **** return retval; } static int ! pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1) { BIGNUM *g2 = NULL, *q2 = NULL; /* Solaris Kerberos */ int retval = EINVAL; --- 3188,3199 ---- return retval; } static int ! pkinit_check_dh_params(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1, ! const BIGNUM *q1) { BIGNUM *g2 = NULL, *q2 = NULL; /* Solaris Kerberos */ int retval = EINVAL;
*** 3022,3061 **** pkiDebug("dh parameters\n"); while (algId[i] != NULL) { DH *dh = NULL; unsigned char *tmp = NULL; int dh_prime_bits = 0; if (algId[i]->algorithm.length != dh_oid.length || memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length)) goto cleanup; tmp = algId[i]->parameters.data; dh = DH_new(); dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length); ! dh_prime_bits = BN_num_bits(dh->p); pkiDebug("client sent %d DH bits server prefers %d DH bits\n", *new_dh_size, dh_prime_bits); switch(dh_prime_bits) { case 1024: ! if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p, ! dh->g, dh->q) == 0) { *new_dh_size = 1024; ok = 1; } break; case 2048: ! if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p, ! dh->g, dh->q) == 0) { *new_dh_size = 2048; ok = 1; } break; case 4096: ! if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p, ! dh->g, dh->q) == 0) { *new_dh_size = 4096; ok = 1; } break; default: --- 3233,3274 ---- pkiDebug("dh parameters\n"); while (algId[i] != NULL) { DH *dh = NULL; unsigned char *tmp = NULL; + const BIGNUM *p, *g, *q, *p2; int dh_prime_bits = 0; if (algId[i]->algorithm.length != dh_oid.length || memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length)) goto cleanup; tmp = algId[i]->parameters.data; dh = DH_new(); dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length); ! dh_prime_bits = DH_bits(dh); pkiDebug("client sent %d DH bits server prefers %d DH bits\n", *new_dh_size, dh_prime_bits); + DH_get0_pqg(dh, &p, &q, &g); switch(dh_prime_bits) { case 1024: ! DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL); ! if (pkinit_check_dh_params(p2, p, g, q) == 0) { *new_dh_size = 1024; ok = 1; } break; case 2048: ! DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL); ! if (pkinit_check_dh_params(p2, p, g, q) == 0) { *new_dh_size = 2048; ok = 1; } break; case 4096: ! DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL); ! if (pkinit_check_dh_params(p2, p, g, q) == 0) { *new_dh_size = 4096; ok = 1; } break; default:
*** 3111,3128 **** } static int openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx) { ! if (!ok) { ! switch (ctx->error) { ! case X509_V_ERR_UNABLE_TO_GET_CRL: ! return 1; ! default: ! return 0; ! } ! } return ok; } static ASN1_OBJECT * pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type) --- 3324,3335 ---- } static int openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx) { ! if (!ok) ! return (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL); return ok; } static ASN1_OBJECT * pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
*** 3307,3344 **** prepare_enc_data(unsigned char *indata, int indata_len, unsigned char **outdata, int *outdata_len) { ! /* Solaris Kerberos */ ! ASN1_const_CTX c; ! long length = indata_len; ! int Ttag, Tclass; ! long Tlen; ! c.pp = (const unsigned char **)&indata; ! c.q = *(const unsigned char **)&indata; ! c.error = ERR_R_NESTED_ASN1_ERROR; ! c.p= *(const unsigned char **)&indata; ! c.max = (length == 0)?0:(c.p+length); ! asn1_GetSequence(&c,&length); ! ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); ! c.p += Tlen; ! ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); ! asn1_const_Finish(&c); ! ! *outdata = (unsigned char *)malloc((size_t)Tlen); ! /* Solaris Kerberos */ ! if (outdata == NULL) return ENOMEM; - (void) memcpy(*outdata, c.p, (size_t)Tlen); - *outdata_len = Tlen; - return 0; } #ifndef WITHOUT_PKCS11 static void * --- 3514,3548 ---- prepare_enc_data(unsigned char *indata, int indata_len, unsigned char **outdata, int *outdata_len) { ! int tag, class; ! long tlen, slen; ! const uint8_t *p = indata, *oldp; ! /* Top-bit set means that the conversion failed. */ ! if (ASN1_get_object(&p, &slen, &tag, &class, indata_len) & 0x80) ! return EINVAL; ! if (tag != V_ASN1_SEQUENCE) ! return EINVAL; ! oldp = p; ! if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80) ! return EINVAL; ! p += tlen; ! slen -= (p - oldp); ! if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80) ! return EINVAL; ! *outdata = malloc(tlen); ! if (*outdata == NULL) return ENOMEM; + memcpy(*outdata, p, tlen); + *outdata_len = tlen; return 0; } #ifndef WITHOUT_PKCS11 static void *
*** 4366,4375 **** --- 4570,4580 ---- { CK_OBJECT_CLASS cls; CK_ATTRIBUTE attrs[4]; CK_ULONG count; CK_KEY_TYPE keytype; + RSA *rsa; unsigned int nattrs = 0; int r; #ifdef PKINIT_USE_KEY_USAGE CK_BBOOL true_false; #endif
*** 4426,4435 **** --- 4631,4641 ---- */ if (r == CKR_OK && count != 1) { EVP_PKEY *priv; X509 *cert; + const BIGNUM *rsan; unsigned int n_len; unsigned char *n_bytes; cert = sk_X509_value(id_cryptoctx->my_certs, 0); priv = X509_get_pubkey(cert);
*** 4457,4473 **** attrs[nattrs].type = CKA_KEY_TYPE; attrs[nattrs].pValue = &keytype; attrs[nattrs].ulValueLen = sizeof keytype; nattrs++; ! n_len = BN_num_bytes(priv->pkey.rsa->n); n_bytes = (unsigned char *) malloc((size_t) n_len); if (n_bytes == NULL) { return (ENOMEM); } ! if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) { free (n_bytes); pkiDebug("zero-byte key modulus\n"); return KRB5KDC_ERR_PREAUTH_FAILED; } --- 4663,4687 ---- attrs[nattrs].type = CKA_KEY_TYPE; attrs[nattrs].pValue = &keytype; attrs[nattrs].ulValueLen = sizeof keytype; nattrs++; ! #if OPENSSL_VERSION_NUMBER < 0x10100000L ! rsa = priv->pkey.rsa; ! rsan = rsa->n; ! n_len = BN_num_bytes(rsan); ! #else ! rsa = EVP_PKEY_get0_RSA(priv); ! RSA_get0_key(rsa, &rsan, NULL, NULL); ! n_len = RSA_size(rsa); ! #endif n_bytes = (unsigned char *) malloc((size_t) n_len); if (n_bytes == NULL) { return (ENOMEM); } ! if (BN_bn2bin(rsan, n_bytes) == 0) { free (n_bytes); pkiDebug("zero-byte key modulus\n"); return KRB5KDC_ERR_PREAUTH_FAILED; }
*** 4772,4786 **** buf_len = EVP_PKEY_size(pkey); buf = (unsigned char *)malloc((size_t) buf_len + 10); if (buf == NULL) return ENOMEM; - #if OPENSSL_VERSION_NUMBER < 0x10000000L - len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey); - #else len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey); - #endif if (len <= 0) { pkiDebug("unable to decrypt received data (len=%d)\n", data_len); /* Solaris Kerberos */ free(buf); return KRB5KRB_ERR_GENERIC; --- 4986,4996 ----
*** 4794,4820 **** static krb5_error_code create_signature(unsigned char **sig, unsigned int *sig_len, unsigned char *data, unsigned int data_len, EVP_PKEY *pkey) { krb5_error_code retval = ENOMEM; ! EVP_MD_CTX md_ctx; if (pkey == NULL) /* Solaris Kerberos */ return EINVAL; ! EVP_VerifyInit(&md_ctx, EVP_sha1()); ! EVP_SignUpdate(&md_ctx, data, data_len); *sig_len = EVP_PKEY_size(pkey); if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL) goto cleanup; ! EVP_SignFinal(&md_ctx, *sig, sig_len, pkey); retval = 0; cleanup: ! EVP_MD_CTX_cleanup(&md_ctx); return retval; } /* --- 5004,5033 ---- static krb5_error_code create_signature(unsigned char **sig, unsigned int *sig_len, unsigned char *data, unsigned int data_len, EVP_PKEY *pkey) { krb5_error_code retval = ENOMEM; ! EVP_MD_CTX *md_ctx; if (pkey == NULL) /* Solaris Kerberos */ return EINVAL; ! if ((md_ctx = EVP_MD_CTX_new()) == NULL) ! return EINVAL; ! ! EVP_VerifyInit(md_ctx, EVP_sha1()); ! EVP_SignUpdate(md_ctx, data, data_len); *sig_len = EVP_PKEY_size(pkey); if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL) goto cleanup; ! EVP_SignFinal(md_ctx, *sig, sig_len, pkey); retval = 0; cleanup: ! EVP_MD_CTX_free(md_ctx); return retval; } /*
*** 6096,6107 **** #ifdef LONGHORN_BETA_COMPAT if (longhorn == 0) { /* XXX Longhorn doesn't like this */ #endif is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); ! M_ASN1_INTEGER_free(is->serial); ! is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = krb5_cas[i]->issuerAndSerialNumber.data = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; i2d_PKCS7_ISSUER_AND_SERIAL(is, &p); --- 6309,6320 ---- #ifdef LONGHORN_BETA_COMPAT if (longhorn == 0) { /* XXX Longhorn doesn't like this */ #endif is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); ! ASN1_INTEGER_free(is->serial); ! is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = krb5_cas[i]->issuerAndSerialNumber.data = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
*** 6301,6312 **** krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial; krb5_cas[i]->u.issuerAndSerial.data = NULL; krb5_cas[i]->u.issuerAndSerial.length = 0; is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); ! M_ASN1_INTEGER_free(is->serial); ! is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = krb5_cas[i]->u.issuerAndSerial.data = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; i2d_PKCS7_ISSUER_AND_SERIAL(is, &p); --- 6514,6525 ---- krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial; krb5_cas[i]->u.issuerAndSerial.data = NULL; krb5_cas[i]->u.issuerAndSerial.length = 0; is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(x)); ! ASN1_INTEGER_free(is->serial); ! is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = krb5_cas[i]->u.issuerAndSerial.data = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
*** 6351,6362 **** if (req_cryptoctx->received_cert == NULL) return 0; is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(cert)); ! M_ASN1_INTEGER_free(is->serial); ! is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; i2d_PKCS7_ISSUER_AND_SERIAL(is, &p); *out_len = len; --- 6564,6575 ---- if (req_cryptoctx->received_cert == NULL) return 0; is = PKCS7_ISSUER_AND_SERIAL_new(); X509_NAME_set(&is->issuer, X509_get_issuer_name(cert)); ! ASN1_INTEGER_free(is->serial); ! is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL); if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL) goto cleanup; i2d_PKCS7_ISSUER_AND_SERIAL(is, &p); *out_len = len;
*** 6537,6549 **** if (cert) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { int tmp_ret = 0; ri=sk_PKCS7_RECIP_INFO_value(rsk,i); tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, ! cert->cert_info->issuer); if (!tmp_ret) { ! tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber, ri->issuer_and_serial->serial); if (!tmp_ret) break; } ri=NULL; --- 6750,6762 ---- if (cert) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { int tmp_ret = 0; ri=sk_PKCS7_RECIP_INFO_value(rsk,i); tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, ! X509_get_issuer_name(cert)); if (!tmp_ret) { ! tmp_ret = ASN1_INTEGER_cmp(X509_get_serialNumber(cert), ri->issuer_and_serial->serial); if (!tmp_ret) break; } ri=NULL;
*** 6560,6571 **** if (cert == NULL) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); jj = pkinit_decode_data(context, id_cryptoctx, ! M_ASN1_STRING_data(ri->enc_key), ! (unsigned int) M_ASN1_STRING_length(ri->enc_key), &tmp, &tmp_len); if (jj) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto cleanup; } --- 6773,6784 ---- if (cert == NULL) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); jj = pkinit_decode_data(context, id_cryptoctx, ! (unsigned char *)ASN1_STRING_get0_data(ri->enc_key), ! ASN1_STRING_length(ri->enc_key), &tmp, &tmp_len); if (jj) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto cleanup; }
*** 6578,6595 **** ERR_clear_error(); ri = NULL; } if (ri == NULL) { ! PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY); goto cleanup; } } else { jj = pkinit_decode_data(context, id_cryptoctx, ! M_ASN1_STRING_data(ri->enc_key), ! (unsigned int) M_ASN1_STRING_length(ri->enc_key), &tmp, &tmp_len); /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */ if (jj || tmp_len == 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto cleanup; --- 6791,6808 ---- ERR_clear_error(); ri = NULL; } if (ri == NULL) { ! PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto cleanup; } } else { jj = pkinit_decode_data(context, id_cryptoctx, ! (unsigned char *)ASN1_STRING_get0_data(ri->enc_key), ! ASN1_STRING_length(ri->enc_key), &tmp, &tmp_len); /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */ if (jj || tmp_len == 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto cleanup;
*** 6609,6619 **** * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ! PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto cleanup; } } if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) goto cleanup; --- 6822,6832 ---- * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ! PKCS7_R_DECRYPT_ERROR); goto cleanup; } } if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) goto cleanup;