]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
added a crl verification function (untested yet).
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 8 Feb 2003 14:46:12 +0000 (14:46 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 8 Feb 2003 14:46:12 +0000 (14:46 +0000)
includes/gnutls/x509.h
lib/gnutls.h.in.in
lib/gnutls_int.h
lib/x509/crl.c
lib/x509/crl.h
lib/x509/verify.c
lib/x509/verify.h
lib/x509/x509.c
lib/x509/x509.h

index 3b54e530b68405b26e28d624a359f4eb084bd651..b9e94897c830888d7328cf38f82585b110ca08ca 100644 (file)
@@ -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
index 2431677f2609d07fa2113eda4fe80e6e610a7f92..101d19da687498cabcab90d8bc3ba4be9dc1de66 100644 (file)
@@ -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);
index aa1206fd9ec78f12acf4566e549e4b2148cda606..d082f0cb42afa8cda4aee57c753fcfe1403b1097 100644 (file)
@@ -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 <gnutls_buffer.h>
 
 /* This is the maximum number of algorithms (ciphers or macs etc).
index b9bc06409c3c04563c6933432c04277846f39b95..c13aa7caec01feb14ea4b821d8ff87fffd200191 100644 (file)
@@ -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;
+
+}
index 8b67d3b227fafd8565e3de8238361d9ca1369977..afb7c57d1de8b9962c47ba627f74bc344bee59a6 100644 (file)
@@ -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
index 81845cf4253aab19db016b6afd237698e05501c5..42547029df8b8b2c72d04838929199b3282c6069 100644 (file)
 #include <verify.h>
 
 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;
 }
index b93fa4e071e9f92b1fef16210104c01c31b68de1..83fdec0c29c7e9d20b268a8eb72b59743e91f447 100644 (file)
@@ -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);
+
index 605a9327fa111001cd80cb08ef6e780a5d9e2839..30b26d821ad8c316349f8aa2654b47c732513698 100644 (file)
@@ -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);
+}
index 057fe907f188e8569ce109f4ed02e200b354b847..f1a3aa16cbb6d542208226989b8e566f3112c745 100644 (file)
@@ -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