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;