From 74a41b918be8bd56d231686c425fdd4aaa7f200a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Mon, 1 May 2006 14:02:50 +0000 Subject: [PATCH] Sprinkel setting error strings. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17391 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/hx509/cert.c | 43 ++++++++++++++++++++++++--------- lib/hx509/ks_file.c | 59 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 23 deletions(-) diff --git a/lib/hx509/cert.c b/lib/hx509/cert.c index f3c59c5b4..c62d8c758 100644 --- a/lib/hx509/cert.c +++ b/lib/hx509/cert.c @@ -106,6 +106,8 @@ hx509_context_init(hx509_context *context) (*context)->ocsp_time_diff = HX509_DEFAULT_OCSP_TIME_DIFF; + initialize_hx_error_table_r(&(*context)->et_list); + return 0; } @@ -126,6 +128,7 @@ hx509_context_free(hx509_context *context) (*context)->ks_ops = NULL; } (*context)->ks_num_ops = 0; + free_error_table ((*context)->et_list); free(*context); *context = NULL; } @@ -489,7 +492,8 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert, static int -check_key_usage(const Certificate *cert, unsigned flags, int req_present) +check_key_usage(hx509_context context, const Certificate *cert, + unsigned flags, int req_present) { const Extension *e; KeyUsage ku; @@ -502,8 +506,12 @@ check_key_usage(const Certificate *cert, unsigned flags, int req_present) e = find_extension(cert, oid_id_x509_ce_keyUsage(), &i); if (e == NULL) { - if (req_present) + if (req_present) { + hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING, + "Required extension key " + "usage missing from certifiate"); return HX509_KU_CERT_MISSING; + } return 0; } @@ -511,21 +519,26 @@ check_key_usage(const Certificate *cert, unsigned flags, int req_present) if (ret) return ret; ku_flags = KeyUsage2int(ku); - if ((ku_flags & flags) != flags) + if ((ku_flags & flags) != flags) { + hx509_set_error_string(context, 0, HX509_KU_CERT_MISSING, + "Key usage missing from certifiate"); return HX509_KU_CERT_MISSING; + } return 0; } int -_hx509_check_key_usage(hx509_cert cert, unsigned flags, int req_present) +_hx509_check_key_usage(hx509_context context, hx509_cert cert, + unsigned flags, int req_present) { - return check_key_usage(_hx509_get_cert(cert), flags, req_present); + return check_key_usage(context, _hx509_get_cert(cert), flags, req_present); } enum certtype { PROXY_CERT, EE_CERT, CA_CERT }; static int -check_basic_constraints(const Certificate *cert, enum certtype type, int depth) +check_basic_constraints(hx509_context context, const Certificate *cert, + enum certtype type, int depth) { BasicConstraints bc; const Extension *e; @@ -541,9 +554,17 @@ check_basic_constraints(const Certificate *cert, enum certtype type, int depth) case PROXY_CERT: case EE_CERT: return 0; - case CA_CERT: + case CA_CERT: { + char *name; + ret = _hx509_unparse_Name(&cert->tbsCertificate.subject, &name); + assert(ret == 0); + hx509_set_error_string(context, 0, HX509_EXTENSION_NOT_FOUND, + "basicConstraints missing from " + "CA certifiacte %s", name); + free(name); return HX509_EXTENSION_NOT_FOUND; } + } } ret = decode_BasicConstraints(e->extnValue.data, @@ -1306,7 +1327,7 @@ hx509_verify_path(hx509_context context, switch (type) { case CA_CERT: - ret = check_key_usage(c, 1 << 5, TRUE); /* XXX make constants */ + ret = check_key_usage(context, c, 1 << 5, TRUE); /* XXX make constants */ if (ret) goto out; break; @@ -1409,7 +1430,7 @@ hx509_verify_path(hx509_context context, break; } - ret = check_basic_constraints(c, type, i - proxy_cert_depth); + ret = check_basic_constraints(context, c, type, i - proxy_cert_depth); if (ret) goto out; @@ -1728,7 +1749,7 @@ hx509_query_free(hx509_context context, hx509_query *q) } int -_hx509_query_match_cert(const hx509_query *q, hx509_cert cert) +_hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert) { Certificate *c = _hx509_get_cert(cert); @@ -1787,7 +1808,7 @@ _hx509_query_match_cert(const hx509_query *q, hx509_cert cert) ku |= (1 << 5); if (q->match & HX509_QUERY_KU_CRLSIGN) ku |= (1 << 6); - if (ku && check_key_usage(c, ku, TRUE)) + if (ku && check_key_usage(context, c, ku, TRUE)) return 0; } if ((q->match & HX509_QUERY_ANCHOR)) diff --git a/lib/hx509/ks_file.c b/lib/hx509/ks_file.c index 6115e21bc..36babf622 100644 --- a/lib/hx509/ks_file.c +++ b/lib/hx509/ks_file.c @@ -108,8 +108,10 @@ parse_certificate(hx509_context context, struct hx509_collector *c, int ret; ret = decode_Certificate(data, len, &t, &size); - if (ret) + if (ret) { + hx509_clear_error_string(context); return ret; + } ret = hx509_cert_init(context, &t, &cert); free_Certificate(&t); @@ -144,26 +146,43 @@ parse_rsa_private_key(hx509_context context, struct hx509_collector *c, hx509_lock lock; lock = _hx509_collector_get_lock(c); - if (lock == NULL) + if (lock == NULL) { + hx509_set_error_string(context, 0, EINVAL, + "Failed to get password for " + "password protected file"); return EINVAL; - + } pw = _hx509_lock_get_passwords(lock); - if (pw == NULL || pw->len < 1) + if (pw == NULL || pw->len < 1) { + hx509_set_error_string(context, 0, EINVAL, + "No passwords when decoding a " + "password protected file"); return EINVAL; + } password = pw->val[0]; passwordlen = strlen(password); - if (strcmp(enc, "4,ENCRYPTED") != 0) + if (strcmp(enc, "4,ENCRYPTED") != 0) { + hx509_set_error_string(context, 0, EINVAL, + "RSA key encrypted in unknown method %s", + enc); + hx509_clear_error_string(context); return EINVAL; + } dek = find_header(headers, "DEK-Info"); - if (dek == NULL) + if (dek == NULL) { + hx509_set_error_string(context, 0, EINVAL, + "Encrypted RSA missing DEK-Info"); return EINVAL; + } type = strdup(dek); - if (type == NULL) + if (type == NULL) { + hx509_clear_error_string(context); return ENOMEM; + } iv = strchr(type, ','); if (iv) @@ -172,6 +191,7 @@ parse_rsa_private_key(hx509_context context, struct hx509_collector *c, size = strlen(iv); ivdata = malloc(size); if (ivdata == NULL) { + hx509_clear_error_string(context); free(type); return ENOMEM; } @@ -180,6 +200,10 @@ parse_rsa_private_key(hx509_context context, struct hx509_collector *c, if (cipher == NULL) { free(type); free(ivdata); + hx509_set_error_string(context, 0, EINVAL, + "RSA key encrypted with " + "unsupported cipher: %s", + type); return EINVAL; } @@ -189,6 +213,7 @@ parse_rsa_private_key(hx509_context context, struct hx509_collector *c, if (ssize < 0 || ssize < PKCS5_SALT_LEN || ssize < EVP_CIPHER_iv_length(cipher)) { free(ivdata); free(type); + hx509_clear_error_string(context); return EINVAL; } @@ -196,6 +221,7 @@ parse_rsa_private_key(hx509_context context, struct hx509_collector *c, if (key == NULL) { free(type); free(ivdata); + hx509_clear_error_string(context); return ENOMEM; } @@ -206,6 +232,8 @@ parse_rsa_private_key(hx509_context context, struct hx509_collector *c, if (ret <= 0) { free(key); free(ivdata); + hx509_clear_error_string(context); + return EINVAL; } @@ -269,9 +297,12 @@ parse_pem_file(hx509_context context, where = BEFORE; *found_data = 0; - if ((f = fopen(fn, "r")) == NULL) + if ((f = fopen(fn, "r")) == NULL) { + hx509_set_error_string(context, 0, ENOENT, + "Failed to open PEM file \"%s\": %s", + fn, strerror(errno)); return ENOENT; - + } ret = 0; while (fgets(buf, sizeof(buf), f) != NULL) { @@ -385,7 +416,7 @@ file_init(hx509_context context, { char *files = NULL, *p, *pnext; int ret; - struct ks_file *f; + struct ks_file *f = NULL; struct hx509_collector *c; *data = NULL; @@ -399,12 +430,14 @@ file_init(hx509_context context, f = calloc(1, sizeof(*f)); if (f == NULL) { + hx509_clear_error_string(context); ret = ENOMEM; goto out; } files = strdup(residue); if (files == NULL) { + hx509_clear_error_string(context); ret = ENOMEM; goto out; } @@ -426,8 +459,10 @@ file_init(hx509_context context, int ret; ret = _hx509_map_file(p, &data, &length, NULL); - if (ret) + if (ret) { + hx509_clear_error_string(context); goto out; + } ret = parse_certificate(context, c, NULL, data, length); _hx509_unmap_file(data, length); @@ -437,11 +472,11 @@ file_init(hx509_context context, } ret = _hx509_collector_collect(context, c, &f->certs); +out: if (ret == 0) *data = f; else free(f); -out: free(files); _hx509_collector_free(c);