adapt to asn1 bignum code, use HEIM_PKINIT errors

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13353 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2004-02-13 16:24:27 +00:00
parent 2e261f0a4b
commit ad01ed478a

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Kungliga Tekniska H<>gskolan
* Copyright (c) 2003 - 2004 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -53,12 +53,6 @@ RCSID("$Id$");
#include "cms_asn1.h"
#include "pkinit_asn1.h"
#define KRB5_AP_ERR_NO_CERT_OR_KEY EINVAL
#define KRB5_AP_ERR_NO_VALID_CA EINVAL
#define KRB5_AP_ERR_CERT EINVAL
#define KRB5_AP_ERR_PRIVATE_KEY EINVAL
#define KRB5_AP_ERR_OPENSSL EINVAL
#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
{ \
unsigned char *p; \
@@ -75,7 +69,7 @@ RCSID("$Id$");
(BL) = i2d_##T((S), &p); \
if ((BL) <= 0) { \
free((B)); \
(R) = KRB5_AP_ERR_OPENSSL; \
(R) = ASN1_OVERRUN; \
} \
} \
} \
@@ -167,7 +161,8 @@ _krb5_pk_create_sign(krb5_context context,
{
const heim_oid *digest_oid;
SignerInfo *signer_info;
X509 *user_cert = NULL;
X509 *user_cert;
heim_big_integer *serial;
krb5_error_code ret;
krb5_data buf;
SignedData sd;
@@ -179,11 +174,15 @@ _krb5_pk_create_sign(krb5_context context,
memset(&sd, 0, sizeof(sd));
if (id == NULL || id->cert == NULL || id->private_key == NULL)
return EINVAL /* KRB5_AP_ERR_NO_CERT_OR_KEY */;
if (id == NULL)
return EINVAL; /* XXX */
if (id->cert == NULL)
return HEIM_PKINIT_NO_CERTIFICATE;
if (id->private_key)
return HEIM_PKINIT_NO_PRIVATE_KEY;
if (sk_X509_num(id->cert) == 0)
return EINVAL /* KRB5_AP_ERR_NO_CERT_OR_KEY */;
return HEIM_PKINIT_NO_CERTIFICATE;
sd.version = 3;
@@ -209,7 +208,7 @@ _krb5_pk_create_sign(krb5_context context,
ALLOC_SEQ(&sd.signerInfos, 1);
if (sd.signerInfos.val == NULL) {
krb5_clear_error_string(context);
krb5_set_error_string(context, "malloc: out of memory");
ret = ENOMEM;
goto out;
}
@@ -217,6 +216,11 @@ _krb5_pk_create_sign(krb5_context context,
signer_info = &sd.signerInfos.val[0];
user_cert = sk_X509_value(id->cert, 0);
if (user_cert == NULL) {
krb5_set_error_string(context, "pkinit: no user certificate");
ret = HEIM_PKINIT_NO_CERTIFICATE;
goto out;
}
signer_info->version = 1;
@@ -227,14 +231,25 @@ _krb5_pk_create_sign(krb5_context context,
buf.length,
issuer_name,
ret);
if (ret)
return ret;
if (ret) {
krb5_set_error_string(context, "pkinit: failed encoding name");
goto out;
}
signer_info->sid.element = choice_SignerIdentifier_issuerAndSerialNumber;
signer_info->sid.u.issuerAndSerialNumber.issuer.data = buf.data;
signer_info->sid.u.issuerAndSerialNumber.issuer.length = buf.length;
signer_info->sid.u.issuerAndSerialNumber.serialNumber =
ASN1_INTEGER_get(X509_get_serialNumber(user_cert));
serial = &signer_info->sid.u.issuerAndSerialNumber.serialNumber;
OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER,
serial->data,
serial->length,
X509_get_serialNumber(user_cert),
ret);
if (ret) {
krb5_set_error_string(context, "pkinit: failed encoding "
"serial number");
goto out;
}
if (context->pkinit_flags & KRB5_PKINIT_PACKET_CABLE)
digest_oid = &heim_sha1_oid;
@@ -360,7 +375,7 @@ _krb5_pk_create_sign(krb5_context context,
}
static int
BN_to_any(krb5_context context, BIGNUM *bn, heim_any *any)
BN_to_integer(krb5_context context, BIGNUM *bn, heim_big_integer *integer)
{
ASN1_INTEGER *i;
int ret;
@@ -369,9 +384,9 @@ BN_to_any(krb5_context context, BIGNUM *bn, heim_any *any)
if (i == NULL) {
krb5_set_error_string(context, "BN_to_ASN1_INTEGER() failed (%s)",
ERR_error_string(ERR_get_error(), NULL));
return KRB5_AP_ERR_OPENSSL;
return ENOMEM;
}
OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, any->data, any->length,
OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, integer->data, integer->length,
i, ret);
ASN1_INTEGER_free(i);
return ret;
@@ -431,17 +446,17 @@ build_auth_pack(krb5_context context,
memset(&dp, 0, sizeof(dp));
ret = BN_to_any(context, dh->p, &dp.p);
ret = BN_to_integer(context, dh->p, &dp.p);
if (ret) {
free_DomainParameters(&dp);
return ret;
}
ret = BN_to_any(context, dh->g, &dp.g);
ret = BN_to_integer(context, dh->g, &dp.g);
if (ret) {
free_DomainParameters(&dp);
return ret;
}
ret = BN_to_any(context, dh->q, &dp.q);
ret = BN_to_integer(context, dh->q, &dp.q);
if (ret) {
free_DomainParameters(&dp);
return ret;
@@ -471,7 +486,7 @@ build_auth_pack(krb5_context context,
if (dh_pub_key == NULL) {
krb5_set_error_string(context, "BN_to_ASN1_INTEGER() failed (%s)",
ERR_error_string(ERR_get_error(), NULL));
return KRB5_AP_ERR_OPENSSL;
return ENOMEM;
}
OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, buf.data, buf.length,
dh_pub_key, ret);
@@ -688,12 +703,17 @@ pk_peer_compare(krb5_context context,
{
switch (peer1->element) {
case choice_SignerIdentifier_issuerAndSerialNumber: {
ASN1_INTEGER *i;
const heim_big_integer *serial;
X509_NAME *name;
unsigned char *p;
size_t len;
if (peer1->u.issuerAndSerialNumber.serialNumber !=
ASN1_INTEGER_get(X509_get_serialNumber(peer2)))
i = X509_get_serialNumber(peer2);
serial = &peer1->u.issuerAndSerialNumber.serialNumber;
if (i->length != serial->length ||
memcmp(i->data, serial->data, i->length) != 0)
return FALSE;
p = peer1->u.issuerAndSerialNumber.issuer.data;
@@ -739,7 +759,7 @@ pk_decrypt_key(krb5_context context,
free(buf);
krb5_set_error_string(context, "Can't decrypt key: %s",
ERR_error_string(ERR_get_error(), NULL));
return KRB5_AP_ERR_OPENSSL;
return ENOMEM;
}
key->keytype = 0;
@@ -785,14 +805,14 @@ pk_verify_chain_standard(krb5_context context,
cert_store = X509_STORE_new();
if (cert_store == NULL) {
ret = KRB5_AP_ERR_OPENSSL;
ret = ENOMEM;
krb5_set_error_string(context, "Can't create X509 store: %s",
ERR_error_string(ERR_get_error(), NULL));
}
store_ctx = X509_STORE_CTX_new();
if (store_ctx == NULL) {
ret = KRB5_AP_ERR_OPENSSL;
ret = ENOMEM;
krb5_set_error_string(context, "Can't create X509 store ctx: %s",
ERR_error_string(ERR_get_error(), NULL));
goto end;
@@ -1596,15 +1616,15 @@ _krb5_pk_load_openssl_id(krb5_context context,
if (cert_file == NULL) {
krb5_set_error_string(context, "certificate file file missing");
return KRB5_AP_ERR_NO_CERT_OR_KEY;
return HEIM_PKINIT_NO_CERTIFICATE;
}
if (key_file == NULL) {
krb5_set_error_string(context, "key file missing");
return KRB5_AP_ERR_NO_CERT_OR_KEY;
return HEIM_PKINIT_NO_PRIVATE_KEY;
}
if (ca_dir == NULL) {
krb5_set_error_string(context, "No root ca directory given\n");
return KRB5_AP_ERR_NO_VALID_CA;
return HEIM_PKINIT_NO_VALID_CA;
}
f = fopen(cert_file, "r");
@@ -1625,7 +1645,7 @@ _krb5_pk_load_openssl_id(krb5_context context,
break;
}
krb5_set_error_string(context, "Can't read certificate");
ret = KRB5_AP_ERR_CERT;
ret = HEIM_PKINIT_CERTIFICATE_INVALID;
fclose(f);
goto out;
}
@@ -1634,7 +1654,7 @@ _krb5_pk_load_openssl_id(krb5_context context,
fclose(f);
if (sk_X509_num(certificate) == 0) {
krb5_set_error_string(context, "No certificate found");
ret = KRB5_AP_ERR_CERT;
ret = HEIM_PKINIT_NO_CERTIFICATE;
goto out;
}
/* load private key */
@@ -1650,12 +1670,12 @@ _krb5_pk_load_openssl_id(krb5_context context,
fclose(f);
if (private_key == NULL) {
krb5_set_error_string(context, "Can't read private key");
ret = KRB5_AP_ERR_PRIVATE_KEY;
ret = HEIM_PKINIT_PRIVATE_KEY_INVALID;
goto out;
}
ret = X509_check_private_key(sk_X509_value(certificate, 0), private_key);
if (ret != 1) {
ret = KRB5_AP_ERR_PRIVATE_KEY;
ret = HEIM_PKINIT_PRIVATE_KEY_INVALID;
krb5_set_error_string(context,
"The private key doesn't match the public key "
"certificate");
@@ -1711,7 +1731,7 @@ _krb5_pk_load_openssl_id(krb5_context context,
if (sk_X509_num(trusted_certs) == 0) {
krb5_set_error_string(context, "No CA certificate(s) found");
ret = KRB5_AP_ERR_NO_VALID_CA;
ret = HEIM_PKINIT_NO_VALID_CA;
goto out;
}