From: Nikos Mavrogiannopoulos Date: Sat, 8 Feb 2003 14:46:12 +0000 (+0000) Subject: added a crl verification function (untested yet). X-Git-Tag: gnutls_0_8_3~62 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=00aef08f3f6446d82dcf0a884ab56e2146b36e82;p=thirdparty%2Fgnutls.git added a crl verification function (untested yet). --- diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h index 3b54e530b6..b9e94897c8 100644 --- a/includes/gnutls/x509.h +++ b/includes/gnutls/x509.h @@ -62,8 +62,8 @@ int gnutls_x509_certificate_get_dn(gnutls_x509_certificate cert, char *buf, int gnutls_x509_certificate_get_dn_by_oid(gnutls_x509_certificate cert, const char* oid, int indx, char *buf, int *sizeof_buf); -int gnutls_x509_certificate_get_signed_data(gnutls_x509_certificate cert, gnutls_datum *data); -int gnutls_x509_certificate_get_signature(gnutls_x509_certificate cert, gnutls_datum *data); +int gnutls_x509_certificate_get_signed_data(gnutls_x509_certificate cert, gnutls_const_datum *data); +int gnutls_x509_certificate_get_signature(gnutls_x509_certificate cert, gnutls_const_datum *data); int gnutls_x509_certificate_get_signature_algorithm(gnutls_x509_certificate cert); int gnutls_x509_certificate_get_version(gnutls_x509_certificate cert); @@ -124,9 +124,9 @@ int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl crl, const char* oid, int indx, char *buf, int *sizeof_buf); -int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_datum *data); +int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_const_datum *data); -int gnutls_x509_crl_get_signature(gnutls_x509_crl crl, gnutls_datum *data); +int gnutls_x509_crl_get_signature(gnutls_x509_crl crl, gnutls_const_datum *data); int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl crl); int gnutls_x509_crl_get_version(gnutls_x509_crl crl); @@ -159,9 +159,27 @@ int gnutls_pkcs7_get_certificate(gnutls_pkcs7 pkcs7, int indx, /* X.509 Certificate verification functions. */ + +typedef enum gnutls_certificate_verify_flags { + GNUTLS_VERIFY_DISABLE_CA_SIGN=1 /* if set a signer does not have to be + * a certificate authority. + */ +} gnutls_certificate_verify_flags; + +int gnutls_x509_certificate_is_issuer( gnutls_x509_certificate cert, + gnutls_x509_certificate issuer); + int gnutls_x509_certificate_list_verify( gnutls_x509_certificate* cert_list, int cert_list_length, gnutls_x509_certificate * CA_list, int CA_list_length, - gnutls_x509_crl * CRL_list, int CRL_list_length, unsigned int *verify); + gnutls_x509_crl* CRL_list, int CRL_list_length, + unsigned int flags, unsigned int *verify); + +int gnutls_x509_certificate_verify( gnutls_x509_certificate cert, + gnutls_x509_certificate *CA_list, int CA_list_length, + unsigned int flags, unsigned int *verify); +int gnutls_x509_crl_verify( gnutls_x509_crl crl, + gnutls_x509_certificate *CA_list, int CA_list_length, + unsigned int flags, unsigned int *verify); #ifdef __cplusplus diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index 2431677f26..101d19da68 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -142,6 +142,11 @@ typedef struct { unsigned int size; } gnutls_datum; +typedef struct { + const unsigned char * data; + unsigned int size; +} gnutls_const_datum; + /* internal functions */ int gnutls_init(gnutls_session * session, gnutls_connection_end con_end); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index aa1206fd9e..d082f0cb42 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -138,6 +138,11 @@ typedef struct { } gnutls_datum; typedef gnutls_datum gnutls_sdatum; +typedef struct { + const opaque * data; + unsigned int size; +} gnutls_const_datum; + #include /* This is the maximum number of algorithms (ciphers or macs etc). diff --git a/lib/x509/crl.c b/lib/x509/crl.c index b9bc06409c..c13aa7caec 100644 --- a/lib/x509/crl.c +++ b/lib/x509/crl.c @@ -275,7 +275,7 @@ int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl crl, const char* oid, * Returns 0 on success. * **/ -int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_datum *data) +int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_const_datum *data) { data->data = crl->signed_data.data; data->size = crl->signed_data.size; @@ -294,7 +294,7 @@ int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_datum *data) * Returns 0 on success. * **/ -int gnutls_x509_crl_get_signature(gnutls_x509_crl crl, gnutls_datum *data) +int gnutls_x509_crl_get_signature(gnutls_x509_crl crl, gnutls_const_datum *data) { data->data = crl->signature.data; data->size = crl->signature.size; @@ -445,3 +445,57 @@ int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index, unsigned cha return 0; } + +/*- + * _gnutls_x509_crl_get_raw_issuer_dn - This function returns the issuer's DN DER encoded + * @crl: should contain a gnutls_x509_crl structure + * @dn: will hold the starting point of the DN + * + * This function will return a pointer to the DER encoded DN structure and + * the length. + * + * Returns a negative value on error, and zero on success. + * + -*/ +int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl, + gnutls_const_datum* dn) +{ + ASN1_TYPE c2 = ASN1_TYPE_EMPTY; + int result, len1; + int start1, end1; + + /* get the issuer of 'crl' + */ + if ((result = + asn1_create_element(_gnutls_get_pkix(), "PKIX1.TBSCertList", + &c2, "c2")) != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding(&c2, crl->signed_data.data, crl->signed_data.size, NULL); + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + gnutls_assert(); + asn1_delete_structure(&c2); + return _gnutls_asn2err(result); + } + + result = + asn1_der_decoding_startEnd(c2, crl->signed_data.data, crl->signed_data.size, + "c2.issuer", &start1, &end1); + asn1_delete_structure(&c2); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + len1 = end1 - start1 + 1; + + dn->data = &crl->signed_data.data[start1]; + dn->size = len1; + + return 0; + +} diff --git a/lib/x509/crl.h b/lib/x509/crl.h index 8b67d3b227..afb7c57d1d 100644 --- a/lib/x509/crl.h +++ b/lib/x509/crl.h @@ -1,3 +1,7 @@ +#ifndef CRL_H +# define CRL_H + +#include "x509.h" typedef struct gnutls_x509_crl_int { ASN1_TYPE crl; @@ -8,3 +12,8 @@ typedef struct gnutls_x509_crl_int { } gnutls_x509_crl_int; typedef struct gnutls_x509_crl_int *gnutls_x509_crl; + +int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl, + gnutls_const_datum* dn); + +#endif diff --git a/lib/x509/verify.c b/lib/x509/verify.c index 81845cf425..42547029df 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -38,9 +38,11 @@ #include static int _gnutls_verify_certificate2(gnutls_x509_certificate cert, - gnutls_x509_certificate *trusted_cas, int tcas_size); + gnutls_x509_certificate *trusted_cas, int tcas_size, + unsigned int flags); static -int _gnutls_x509_verify_signature(gnutls_x509_certificate cert, gnutls_x509_certificate issuer); +int _gnutls_x509_verify_signature(const gnutls_datum* signed_data, + const gnutls_datum* signature, gnutls_x509_certificate issuer); /* Checks if the issuer of a certificate is a @@ -87,88 +89,62 @@ static int check_if_ca(gnutls_x509_certificate cert, * a negative value is returned to indicate error. */ static -int compare_dn(gnutls_x509_certificate cert, gnutls_x509_certificate issuer_cert) +int is_issuer(gnutls_x509_certificate cert, gnutls_x509_certificate issuer_cert) { - ASN1_TYPE c2, c3; - int result, len1; - int len2; - int start1, start2, end1, end2; + gnutls_const_datum dn1, dn2; + int ret; - /* get the issuer of 'cert' - */ - if ((result = - _gnutls_asn1_create_element(_gnutls_get_pkix(), "PKIX1.TBSCertificate", - &c2, "c2")) != ASN1_SUCCESS) { + ret = _gnutls_x509_certificate_get_raw_issuer_dn( cert, &dn1); + if (ret < 0) { gnutls_assert(); - return _gnutls_asn2err(result); + return ret; } - result = asn1_der_decoding(&c2, cert->signed_data.data, cert->signed_data.size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ + ret = _gnutls_x509_certificate_get_raw_dn( issuer_cert, &dn2); + if (ret < 0) { gnutls_assert(); - asn1_delete_structure(&c2); - return _gnutls_asn2err(result); + return ret; } - - /* get the 'subject' info of 'issuer_cert' - */ - if ((result = - _gnutls_asn1_create_element(_gnutls_get_pkix(), "PKIX1.TBSCertificate", - &c3, "c3")) != ASN1_SUCCESS) { + if (dn1.size != dn2.size) { gnutls_assert(); - asn1_delete_structure(&c2); - return _gnutls_asn2err(result); + return 0; } - - result = - asn1_der_decoding(&c3, issuer_cert->signed_data.data, issuer_cert->signed_data.size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ + if (memcmp(dn1.data, dn2.data, dn2.size) != 0) { gnutls_assert(); - asn1_delete_structure(&c2); - asn1_delete_structure(&c3); - return _gnutls_asn2err(result); + return 0; } + /* they match */ + return 1; - result = - asn1_der_decoding_startEnd(c2, cert->signed_data.data, cert->signed_data.size, - "c2.issuer", &start1, &end1); - asn1_delete_structure(&c2); +} - if (result != ASN1_SUCCESS) { +/* The same as above, but here we've got a CRL. + */ +static +int is_crl_issuer(gnutls_x509_crl crl, gnutls_x509_certificate issuer_cert) +{ + gnutls_const_datum dn1, dn2; + int ret; + + ret = _gnutls_x509_crl_get_raw_issuer_dn( crl, &dn1); + if (ret < 0) { gnutls_assert(); - asn1_delete_structure(&c3); - return _gnutls_asn2err(result); + return ret; } - len1 = end1 - start1 + 1; - - result = - asn1_der_decoding_startEnd(c3, issuer_cert->signed_data.data, - issuer_cert->signed_data.size, - "c3.subject", - &start2, &end2); - asn1_delete_structure(&c3); - - if (result != ASN1_SUCCESS) { + ret = _gnutls_x509_certificate_get_raw_dn( issuer_cert, &dn2); + if (ret < 0) { gnutls_assert(); - return _gnutls_asn2err(result); + return ret; } - len2 = end2 - start2 + 1; - - /* The error code returned does not really matter - * here. - */ - if (len1 != len2) { + if (dn1.size != dn2.size) { gnutls_assert(); return 0; } - if (memcmp(&issuer_cert->signed_data.data[start2], - &cert->signed_data.data[start1], len1) != 0) { + if (memcmp(dn1.data, dn2.data, dn2.size) != 0) { gnutls_assert(); return 0; } @@ -178,7 +154,8 @@ int compare_dn(gnutls_x509_certificate cert, gnutls_x509_certificate issuer_cert } -static gnutls_x509_certificate find_issuer(gnutls_x509_certificate cert, +static inline +gnutls_x509_certificate find_crl_issuer(gnutls_x509_crl crl, gnutls_x509_certificate * trusted_cas, int tcas_size) { int i; @@ -187,7 +164,7 @@ static gnutls_x509_certificate find_issuer(gnutls_x509_certificate cert, */ for (i = 0; i < tcas_size; i++) { - if (compare_dn(cert, trusted_cas[i]) == 1) + if (is_crl_issuer(crl, trusted_cas[i]) == 1) return trusted_cas[i]; } @@ -195,12 +172,37 @@ static gnutls_x509_certificate find_issuer(gnutls_x509_certificate cert, return NULL; } + + +static inline +gnutls_x509_certificate find_issuer(gnutls_x509_certificate cert, + gnutls_x509_certificate * trusted_cas, int tcas_size) +{ + int i; + + /* this is serial search. + */ + + for (i = 0; i < tcas_size; i++) { + if (is_issuer(cert, trusted_cas[i]) == 1) + return trusted_cas[i]; + } + + gnutls_assert(); + return NULL; +} + + + /* * Returns only 0 or 1. If 1 it means that the certificate * was successfuly verified. + * + * 'flags': an OR of the gnutls_certificate_verify_flags enumeration. */ static int _gnutls_verify_certificate2(gnutls_x509_certificate cert, - gnutls_x509_certificate *trusted_cas, int tcas_size) + gnutls_x509_certificate *trusted_cas, int tcas_size, + unsigned int flags) { /* CRL is ignored for now */ @@ -222,12 +224,62 @@ static int _gnutls_verify_certificate2(gnutls_x509_certificate cert, return 0; } - if (check_if_ca(cert, issuer)==0) { + if (flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) { + if (check_if_ca(cert, issuer)==0) { + gnutls_assert(); + return 0; + } + } + + ret = _gnutls_x509_verify_signature(&cert->signed_data, &cert->signature, issuer); + if (ret < 0) { + gnutls_assert(); + /* error. ignore it */ + ret = 0; + } + + return ret; +} + +/* + * Returns only 0 or 1. If 1 it means that the CRL + * was successfuly verified. + * + * 'flags': an OR of the gnutls_certificate_verify_flags enumeration. + */ +static int _gnutls_verify_crl2(gnutls_x509_crl crl, + gnutls_x509_certificate *trusted_cas, int tcas_size, + unsigned int flags) +{ +/* CRL is ignored for now */ + + gnutls_x509_certificate issuer; + int ret; + + if (tcas_size >= 1) + issuer = find_crl_issuer(crl, trusted_cas, tcas_size); + else { + gnutls_assert(); + return 0; + } + + /* issuer is not in trusted certificate + * authorities. + */ + if (issuer == NULL) { gnutls_assert(); return 0; } - ret = _gnutls_x509_verify_signature(cert, issuer); + if (flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) { + if (gnutls_x509_certificate_get_ca_status(issuer, NULL) != 1) + { + gnutls_assert(); + return 0; + } + } + + ret = _gnutls_x509_verify_signature(&crl->signed_data, &crl->signature, issuer); if (ret < 0) { gnutls_assert(); /* error. ignore it */ @@ -237,6 +289,7 @@ static int _gnutls_verify_certificate2(gnutls_x509_certificate cert, return ret; } + /* The algorithm used is: * 1. Check the certificate chain given by the peer, if it is ok. * 2. If any certificate in the chain are revoked, not @@ -255,7 +308,7 @@ unsigned int _gnutls_x509_verify_certificate(gnutls_x509_certificate * certifica int clist_size, gnutls_x509_certificate * trusted_cas, int tcas_size, gnutls_x509_crl *CRLs, - int crls_size) + int crls_size, unsigned int flags) { int i = 0, ret; unsigned int status = 0; @@ -267,7 +320,7 @@ unsigned int _gnutls_x509_verify_certificate(gnutls_x509_certificate * certifica if ((ret = _gnutls_verify_certificate2(certificate_list[i], - &certificate_list[i + 1], 1)) != 1) + &certificate_list[i + 1], 1, flags)) != 1) { status |= GNUTLS_CERT_INVALID; } @@ -288,7 +341,7 @@ unsigned int _gnutls_x509_verify_certificate(gnutls_x509_certificate * certifica */ ret = _gnutls_verify_certificate2(certificate_list[i], trusted_cas, - tcas_size); + tcas_size, flags); if (ret == 0) { /* if the last certificate in the certificate @@ -379,7 +432,8 @@ int len; * params[1] is public key */ static int -_pkcs1_rsa_verify_sig( const gnutls_datum* signature, gnutls_datum* text, GNUTLS_MPI *params, int params_len) +_pkcs1_rsa_verify_sig( const gnutls_datum* text, const gnutls_datum* signature, + GNUTLS_MPI *params, int params_len) { gnutls_mac_algorithm hash; int ret; @@ -424,18 +478,17 @@ _pkcs1_rsa_verify_sig( const gnutls_datum* signature, gnutls_datum* text, GNUTLS /* verifies if the certificate is properly signed. * returns 0 on failure and 1 on success. + * + * 'tbs' is the signed data + * 'signature' is the signature! */ static -int _gnutls_x509_verify_signature(gnutls_x509_certificate cert, gnutls_x509_certificate issuer) +int _gnutls_x509_verify_signature( const gnutls_datum* tbs, + const gnutls_datum* signature, gnutls_x509_certificate issuer) { -gnutls_datum signature; -gnutls_datum tbs; GNUTLS_MPI issuer_params[MAX_PARAMS_SIZE]; int ret, issuer_params_size, i; - signature = cert->signature; - tbs = cert->signed_data; - /* Read the MPI parameters from the issuer's certificate. */ issuer_params_size = MAX_PARAMS_SIZE; @@ -450,7 +503,7 @@ int ret, issuer_params_size, i; { case GNUTLS_PK_RSA: - if (_pkcs1_rsa_verify_sig( &signature, &tbs, issuer_params, issuer_params_size)!=0) { + if (_pkcs1_rsa_verify_sig( tbs, signature, issuer_params, issuer_params_size)!=0) { gnutls_assert(); ret = 0; goto finish; @@ -461,7 +514,7 @@ int ret, issuer_params_size, i; break; case GNUTLS_PK_DSA: - if (_gnutls_dsa_verify( &tbs, &signature, issuer_params, issuer_params_size)!=0) { + if (_gnutls_dsa_verify( tbs, signature, issuer_params, issuer_params_size)!=0) { gnutls_assert(); ret = 0; goto finish; @@ -495,15 +548,17 @@ int ret, issuer_params_size, i; * @CA_list_length: holds the number of CA certificate in CA_list * @CRL_list: holds a list of CRLs. * @CRL_list_length: the length of CRL list. + * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations. * @verify: will hold the certificate verification output. * - * This function will try to verify the given certificate list and return it's status (TRUSTED, EXPIRED etc.). + * This function will try to verify the given certificate list and return it's status (TRUSTED, REVOKED etc.). * The return value (status) should be one or more of the gnutls_certificate_status * enumerated elements bitwise or'd. Note that expiration and activation dates are not checked * by this function, you should check them using the appropriate functions. * - * This function uses the basicConstraints (2 5 29 19) PKIX extension. - * This means that only a certificate authority can sign a certificate. + * If no flags are specified (0), this function will use the + * basicConstraints (2 5 29 19) PKIX extension. This means that only a certificate + * authority is allowed to sign a certificate. * * However you must also check the peer's name in order to check if the verified * certificate belongs to the actual peer. @@ -526,7 +581,8 @@ int ret, issuer_params_size, i; **/ int gnutls_x509_certificate_list_verify( gnutls_x509_certificate* cert_list, int cert_list_length, gnutls_x509_certificate * CA_list, int CA_list_length, - gnutls_x509_crl* CRL_list, int CRL_list_length, unsigned int *verify) + gnutls_x509_crl* CRL_list, int CRL_list_length, + unsigned int flags, unsigned int *verify) { if (cert_list == NULL || cert_list_length == 0) return GNUTLS_E_NO_CERTIFICATE_FOUND; @@ -535,7 +591,97 @@ int gnutls_x509_certificate_list_verify( gnutls_x509_certificate* cert_list, int */ *verify = _gnutls_x509_verify_certificate( cert_list, cert_list_length, - CA_list, CA_list_length, CRL_list, CRL_list_length); + CA_list, CA_list_length, CRL_list, CRL_list_length, flags); + + return 0; +} + +/** + * gnutls_x509_certificate_verify - This function verifies the given certificate against a given trusted one + * @cert: is the certificate to be verified + * @CA_list: is one certificate that is considered to be trusted one + * @CA_list_length: holds the number of CA certificate in CA_list + * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations. + * @verify: will hold the certificate verification output. + * + * This function will try to verify the given certificate and return it's status. + * See gnutls_x509_certificate_list_verify() for a detailed description of + * return values. + * + * Returns 0 on success and a negative value in case of an error. + * + **/ +int gnutls_x509_certificate_verify( gnutls_x509_certificate cert, + gnutls_x509_certificate *CA_list, int CA_list_length, + unsigned int flags, unsigned int *verify) +{ + /* Verify certificate + */ + *verify = + _gnutls_verify_certificate2( cert, CA_list, CA_list_length, flags); + + return 0; +} + +/** + * gnutls_x509_certificate_is_issuer - This function checks if the certificate given has the given issuer + * @cert: is the certificate to be checked + * @issuer: is the certificate of a possible issuer + * + * This function will check if the given certificate was issued by the + * given issuer. It will return true (1) if the given certificate is issued + * by the given issuer, and false (0) if not. + * + * A negative value is returned in case of an error. + * + **/ +int gnutls_x509_certificate_is_issuer( gnutls_x509_certificate cert, + gnutls_x509_certificate issuer) +{ + return is_issuer(cert, issuer); +} + +/** + * gnutls_x509_crl_is_issuer - This function checks if the CRL given has the given issuer + * @crl: is the CRL to be checked + * @issuer: is the certificate of a possible issuer + * + * This function will check if the given CRL was issued by the + * given issuer certificate. It will return true (1) if the given CRL was issued + * by the given issuer, and false (0) if not. + * + * A negative value is returned in case of an error. + * + **/ +int gnutls_x509_crl_is_issuer( gnutls_x509_crl cert, + gnutls_x509_certificate issuer) +{ + return is_crl_issuer(cert, issuer); +} + +/** + * gnutls_x509_crl_verify - This function verifies the given crl against a given trusted one + * @crl: is the crl to be verified + * @CA_list: is a certificate list that is considered to be trusted one + * @CA_list_length: holds the number of CA certificates in CA_list + * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations. + * @verify: will hold the crl verification output. + * + * This function will try to verify the given crl and return it's status. + * See gnutls_x509_certificate_list_verify() for a detailed description of + * return values. + * + * Returns 0 on success and a negative value in case of an error. + * + **/ +int gnutls_x509_crl_verify( gnutls_x509_crl crl, + gnutls_x509_certificate *CA_list, int CA_list_length, + unsigned int flags, unsigned int *verify) +{ + /* Verify crl + */ + *verify = + _gnutls_verify_crl2( crl, CA_list, CA_list_length, flags); return 0; } diff --git a/lib/x509/verify.h b/lib/x509/verify.h index b93fa4e071..83fdec0c29 100644 --- a/lib/x509/verify.h +++ b/lib/x509/verify.h @@ -1,3 +1,20 @@ +#include "x509.h" + +typedef enum gnutls_certificate_verify_flags { + GNUTLS_VERIFY_DISABLE_CA_SIGN=1 +} gnutls_certificate_verify_flags; + +int gnutls_x509_certificate_is_issuer( gnutls_x509_certificate cert, + gnutls_x509_certificate issuer); +int gnutls_x509_certificate_verify( gnutls_x509_certificate cert, + gnutls_x509_certificate *CA_list, int CA_list_length, + unsigned int flags, unsigned int *verify); +int gnutls_x509_crl_verify( gnutls_x509_crl crl, + gnutls_x509_certificate *CA_list, int CA_list_length, + unsigned int flags, unsigned int *verify); + int gnutls_x509_certificate_list_verify( gnutls_x509_certificate* cert_list, int cert_list_length, gnutls_x509_certificate * CA_list, int CA_list_length, - gnutls_x509_crl* CRL_list, int CRL_list_length, unsigned int* verify); + gnutls_x509_crl* CRL_list, int CRL_list_length, + unsigned int flags, unsigned int *verify); + diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 605a9327fa..30b26d821a 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -345,7 +345,7 @@ int gnutls_x509_certificate_get_dn_by_oid(gnutls_x509_certificate cert, const ch * Returns 0 on success. * **/ -int gnutls_x509_certificate_get_signed_data(gnutls_x509_certificate cert, gnutls_datum *data) +int gnutls_x509_certificate_get_signed_data(gnutls_x509_certificate cert, gnutls_const_datum *data) { data->data = cert->signed_data.data; data->size = cert->signed_data.size; @@ -364,7 +364,7 @@ int gnutls_x509_certificate_get_signed_data(gnutls_x509_certificate cert, gnutls * Returns 0 on success. * **/ -int gnutls_x509_certificate_get_signature(gnutls_x509_certificate cert, gnutls_datum *data) +int gnutls_x509_certificate_get_signature(gnutls_x509_certificate cert, gnutls_const_datum *data) { data->data = cert->signature.data; data->size = cert->signature.size; @@ -817,3 +817,82 @@ int gnutls_x509_certificate_get_extension_by_oid(gnutls_x509_certificate cert, c return 0; } + + +static +int _gnutls_x509_certificate_get_raw_dn2( gnutls_x509_certificate cert, + const char* whom, gnutls_const_datum* start) +{ + ASN1_TYPE c2 = ASN1_TYPE_EMPTY; + int result, len1; + int start1, end1; + + /* get the issuer of 'cert' + */ + if ((result = + asn1_create_element(_gnutls_get_pkix(), "PKIX1.TBSCertificate", + &c2, "c2")) != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding(&c2, cert->signed_data.data, cert->signed_data.size, NULL); + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + gnutls_assert(); + asn1_delete_structure(&c2); + return _gnutls_asn2err(result); + } + + result = + asn1_der_decoding_startEnd(c2, cert->signed_data.data, cert->signed_data.size, + whom, &start1, &end1); + asn1_delete_structure(&c2); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + len1 = end1 - start1 + 1; + + start->data = &cert->signed_data.data[start1]; + start->size = len1; + + return 0; + +} + +/*- + * _gnutls_x509_certificate_get_raw_issuer_dn - This function returns the issuer's DN DER encoded + * @cert: should contain a gnutls_x509_certificate structure + * @start: will hold the starting point of the DN + * + * This function will return a pointer to the DER encoded DN structure and + * the length. + * + * Returns a negative value on error, and zero on success. + * + -*/ +int _gnutls_x509_certificate_get_raw_issuer_dn( gnutls_x509_certificate cert, + gnutls_const_datum* start) +{ + return _gnutls_x509_certificate_get_raw_dn2( cert, "c2.issuer", start); +} + +/*- + * _gnutls_x509_certificate_get_raw_dn - This function returns the subject's DN DER encoded + * @cert: should contain a gnutls_x509_certificate structure + * @start: will hold the starting point of the DN + * + * This function will return a pointer to the DER encoded DN structure and + * the length. + * + * Returns a negative value on error, and zero on success. + * + -*/ +int _gnutls_x509_certificate_get_raw_dn( gnutls_x509_certificate cert, + gnutls_const_datum * start) +{ + return _gnutls_x509_certificate_get_raw_dn2( cert, "c2.subject", start); +} diff --git a/lib/x509/x509.h b/lib/x509/x509.h index 057fe907f1..f1a3aa16cb 100644 --- a/lib/x509/x509.h +++ b/lib/x509/x509.h @@ -20,4 +20,10 @@ int gnutls_x509_certificate_get_dn_by_oid(gnutls_x509_certificate cert, const ch int gnutls_x509_certificate_get_ca_status(gnutls_x509_certificate cert, int* critical); int gnutls_x509_certificate_get_pk_algorithm( gnutls_x509_certificate cert, int* bits); +int _gnutls_x509_certificate_get_raw_issuer_dn( gnutls_x509_certificate cert, + gnutls_const_datum* start); +int _gnutls_x509_certificate_get_raw_dn( gnutls_x509_certificate cert, + gnutls_const_datum* start); + + #endif