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