]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Improved the certificate generation stuff.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 25 Oct 2003 15:29:01 +0000 (15:29 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 25 Oct 2003 15:29:01 +0000 (15:29 +0000)
12 files changed:
includes/gnutls/x509.h
lib/x509/common.c
lib/x509/common.h
lib/x509/crl.c
lib/x509/dn.c
lib/x509/extensions.c
lib/x509/extensions.h
lib/x509/mpi.c
lib/x509/verify.c
lib/x509/x509.c
lib/x509/x509.h
lib/x509/x509_write.c

index f40076e5a64bd98968cb598c77b218b979617757..55a90f94482595c46048ef92a45e6bcdbf8eb59b 100644 (file)
@@ -114,6 +114,8 @@ int gnutls_x509_crt_set_issuer_dn_by_oid(gnutls_x509_crt crt, const char* oid,
 int gnutls_x509_crt_set_version(gnutls_x509_crt crt, unsigned int version);
 int gnutls_x509_crt_set_key(gnutls_x509_crt crt, gnutls_x509_privkey key);
 int gnutls_x509_crt_set_ca_status(gnutls_x509_crt crt, unsigned int ca);
+int gnutls_x509_crt_set_subject_alternative_name(gnutls_x509_crt crt, gnutls_x509_subject_alt_name type,
+       const char* data_string);
 int gnutls_x509_crt_sign(gnutls_x509_crt crt, gnutls_x509_crt issuer, 
        gnutls_x509_privkey issuer_key);
 int gnutls_x509_crt_set_activation_time(gnutls_x509_crt cert, time_t act_time);
index c7ce6fb5c135aa4221ec5a43e2d5902626b0b8c0..01d3048187d34853153c2d8e41d322fd13710b62 100644 (file)
@@ -1126,3 +1126,100 @@ int _gnutls_asn1_copy_node( ASN1_TYPE *dst, const char* dst_name,
        
        return 0;
 }
+
+/* Reads the DER signed data from the certificate and allocates space and
+ * returns them into signed_data.
+ */
+int _gnutls_x509_get_signed_data( ASN1_TYPE src, const char* src_name, gnutls_datum * signed_data)
+{
+gnutls_datum der;
+int start, end, result;
+
+       result = _gnutls_x509_der_encode( src, "", &der, 0);
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+        
+       /* Get the signed data
+        */
+       result = asn1_der_decoding_startEnd( src, der.data, der.size,
+                                           src_name, &start,
+                                           &end);
+       if (result != ASN1_SUCCESS) {
+               result = _gnutls_asn2err(result);
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result =
+           _gnutls_set_datum( signed_data, &der.data[start], end - start + 1);
+
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = 0;
+
+      cleanup:
+       _gnutls_free_datum(&der);
+
+       return result;
+}      
+
+/* Reads the DER signature from the certificate and allocates space and
+ * returns them into signed_data.
+ */
+int _gnutls_x509_get_signature( ASN1_TYPE src, const char* src_name, gnutls_datum * signature)
+{
+int bits, result, len;
+
+       signature->data = NULL;
+       signature->size = 0;
+
+       /* Read the signature 
+        */
+       bits = 0;
+       result = asn1_read_value( src, src_name, NULL, &bits);
+
+       if (result != ASN1_MEM_ERROR) {
+               result = _gnutls_asn2err(result);
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       if (bits % 8 != 0) {
+               gnutls_assert();
+               result = GNUTLS_E_CERTIFICATE_ERROR;
+               goto cleanup;
+       }
+
+       len = bits/8;
+
+       signature->data = gnutls_malloc( len);
+       if (signature->data == NULL) {
+               gnutls_assert();
+               result = GNUTLS_E_MEMORY_ERROR;
+               return result;
+       }
+               
+       /* read the bit string of the signature
+        */
+       bits = len;
+       result = asn1_read_value( src, src_name, signature->data,
+               &bits);
+
+       if (result != ASN1_SUCCESS) {
+               result = _gnutls_asn2err(result);
+               gnutls_assert();
+               goto cleanup;
+       }
+               
+       signature->size = len;
+
+       return 0;
+
+      cleanup:
+       return result;
+}
index 6f286fafb4cbf5b85d6893672c237e4186ef8a5f..0eb81c84d929c36f1c80b95877d0911ab4505fcb 100644 (file)
@@ -65,3 +65,6 @@ int _gnutls_x509_encode_and_copy_PKI_params( ASN1_TYPE dst, const char* dst_name
        gnutls_pk_algorithm pk_algorithm, GNUTLS_MPI* params, int params_size);
 int _gnutls_asn1_copy_node( ASN1_TYPE *dst, const char* dst_name,
        ASN1_TYPE src, const char* src_name);
+
+int _gnutls_x509_get_signed_data( ASN1_TYPE src, const char* src_name, gnutls_datum * signed_data);
+int _gnutls_x509_get_signature( ASN1_TYPE src, const char* src_name, gnutls_datum * signature);
index 031055d37ae7d277d2cc5df7ed48d09444a9b7b0..5745e37fbfe0362ea95a0fd23840994f2be680d4 100644 (file)
@@ -75,8 +75,6 @@ void gnutls_x509_crl_deinit(gnutls_x509_crl crl)
 
        if (crl->crl)
                asn1_delete_structure(&crl->crl);
-       _gnutls_free_datum(&crl->signed_data);
-       _gnutls_free_datum(&crl->signature);
 
        gnutls_free(crl);
 }
@@ -99,9 +97,7 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
                           gnutls_x509_crt_fmt format)
 {
        int result = 0, need_free = 0;
-       int start, end, bits, len;
        gnutls_datum _data = { data->data, data->size };
-       opaque *signature = NULL;
 
        /* If the CRL is in PEM format then decode it
         */
@@ -134,94 +130,12 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
                goto cleanup;
        }
 
-       /* Get the signed data
-        */
-       result =
-           asn1_der_decoding_startEnd(crl->crl, _data.data, _data.size,
-                                      "tbsCertList", &start, &end);
-       if (result != ASN1_SUCCESS) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-
-
-       result =
-           _gnutls_set_datum(&crl->signed_data, &_data.data[start],
-                             end - start + 1);
-       if (result < 0) {
-               gnutls_assert();
-               goto cleanup;
-       }
-
-       /* Read the signature */
-       bits = 0;
-       result = asn1_read_value( crl->crl, "signature", NULL, &bits);
-               
-       if (result != ASN1_MEM_ERROR) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-
-       if (bits % 8 != 0) {
-               gnutls_assert();
-               result = GNUTLS_E_CERTIFICATE_ERROR;
-               goto cleanup;
-       }
-
-       len = bits/8;
-       signature = gnutls_malloc( len);
-       if (signature == NULL) {
-               gnutls_assert();
-               return GNUTLS_E_MEMORY_ERROR;
-       }
-               
-       /* read the bit string of the signature
-        */
-       bits = len;
-       result = asn1_read_value( crl->crl, "signature", signature,
-               &bits);
-
-       if (result != ASN1_SUCCESS) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-               
-               
-       if ((result=_gnutls_set_datum(&crl->signature, signature, len)) < 0) {
-               gnutls_assert();
-               goto cleanup;
-       }
-               
-       /* Read the signature algorithm. Note that parameters are not
-        * read. They will be read from the issuer's certificate if needed.
-        */
-               
-       result = asn1_read_value( crl->crl, "signatureAlgorithm.algorithm",
-               signature, &len);
-               
-       if (result != ASN1_SUCCESS) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-
-       crl->signature_algorithm = _gnutls_x509_oid2sign_algorithm( signature, NULL);
-               
-       gnutls_free( signature);
-       signature = NULL;
-
        if (need_free)
                _gnutls_free_datum(&_data);
 
        return 0;
 
       cleanup:
-       gnutls_free( signature);
-       _gnutls_free_datum(&crl->signed_data);
-       _gnutls_free_datum(&crl->signature);
        if (need_free)
                _gnutls_free_datum(&_data);
        return result;
@@ -305,9 +219,25 @@ int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl crl,
   **/
 int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl crl)
 {
-       return crl->signature_algorithm;
+       int result;
+       gnutls_datum sa;
 
-       return 0;
+       /* Read the signature algorithm. Note that parameters are not
+        * read. They will be read from the issuer's certificate if needed.
+        */
+               
+       result = _gnutls_x509_read_value( crl->crl, "signatureAlgorithm.algorithm", &sa, 0);
+               
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+       
+       result = _gnutls_x509_oid2sign_algorithm( sa.data, NULL);
+
+       _gnutls_free_datum( &sa);
+
+       return result;
 }
 
 /**
@@ -460,11 +390,12 @@ int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index,
   *
   -*/
 int _gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl crl,
-                                      gnutls_const_datum * dn)
+                                      gnutls_datum * dn)
 {
        ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
        int result, len1;
        int start1, end1;
+       gnutls_datum crl_signed_data;
 
        /* get the issuer of 'crl'
         */
@@ -475,34 +406,44 @@ int _gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl crl,
                return _gnutls_asn2err(result);
        }
 
+       result = _gnutls_x509_get_signed_data( crl->crl, "tbsCertList", &crl_signed_data);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
        result =
-           asn1_der_decoding(&c2, crl->signed_data.data,
-                             crl->signed_data.size, NULL);
+           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 = _gnutls_asn2err(result);
+               goto cleanup;
        }
 
        result =
-           asn1_der_decoding_startEnd(c2, crl->signed_data.data,
-                                      crl->signed_data.size, "issuer",
+           asn1_der_decoding_startEnd(c2, crl_signed_data.data,
+                                      crl_signed_data.size, "issuer",
                                       &start1, &end1);
-       asn1_delete_structure(&c2);
 
        if (result != ASN1_SUCCESS) {
                gnutls_assert();
-               return _gnutls_asn2err(result);
+               result = _gnutls_asn2err(result);
+               goto cleanup;
        }
 
        len1 = end1 - start1 + 1;
 
-       dn->data = &crl->signed_data.data[start1];
-       dn->size = len1;
+       _gnutls_set_datum( dn, &crl_signed_data.data[start1], len1);
 
-       return 0;
+       result = 0;
 
+cleanup:
+       asn1_delete_structure(&c2);
+       _gnutls_free_datum( &crl_signed_data);
+       return result;
 }
 
 /**
index 35f6146363c3447c97315b7caddf4f1241808609..8bfd8e37d7ea38fa9533bae8b6a18540c8295a95 100644 (file)
@@ -811,8 +811,8 @@ int gnutls_x509_rdn_get_by_oid(const gnutls_datum * idn, const char* oid, int in
  * Returns 1 if the DN's match and zero if they don't match. Otherwise
  * a negative value is returned to indicate error.
  */
-int _gnutls_x509_compare_raw_dn(const gnutls_const_datum * dn1,
-       const gnutls_const_datum * dn2) 
+int _gnutls_x509_compare_raw_dn(const gnutls_datum * dn1,
+       const gnutls_datum * dn2) 
 {
 
        if (dn1->size != dn2->size) {
index 785559013475f715e1e6687139103beecb3d0a03..c6e4e0e1e9ae44918e84e90fc2945c9712dc7714 100644 (file)
@@ -34,6 +34,9 @@
  * ret.
  *
  * Critical will be either 0 or 1.
+ *
+ * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
+ * be returned.
  */
 int _gnutls_x509_crt_get_extension( gnutls_x509_crt cert, const char* extension_id, 
        int indx, gnutls_datum* ret, unsigned int * _critical)
@@ -303,9 +306,8 @@ int _gnutls_x509_ext_gen_basicConstraints(int CA, gnutls_datum* der_ext)
        if (CA == 0) str = "FALSE";
        else str = "TRUE";
 
-       if ((result=asn1_create_element
-           (_gnutls_get_pkix(), "PKIX1.BasicConstraints", &ext
-            )) != ASN1_SUCCESS) {
+       result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.BasicConstraints", &ext);
+       if (result != ASN1_SUCCESS) {
                gnutls_assert();
                return _gnutls_asn2err(result);
        }
@@ -316,6 +318,8 @@ int _gnutls_x509_ext_gen_basicConstraints(int CA, gnutls_datum* der_ext)
                asn1_delete_structure(&ext);
                return _gnutls_asn2err(result);
        }
+
+       asn1_write_value(ext, "pathLenConstraint", NULL, 0);
        
        result = _gnutls_x509_der_encode( ext, "", der_ext, 0);
 
@@ -328,3 +332,71 @@ int _gnutls_x509_ext_gen_basicConstraints(int CA, gnutls_datum* der_ext)
 
        return 0;
 }
+
+/* generate the subject alternative name in a DER encoded extension
+ */
+int _gnutls_x509_ext_gen_subject_alt_name(gnutls_x509_subject_alt_name type, 
+       const char* data_string, gnutls_datum* der_ext)
+{
+       ASN1_TYPE ext = ASN1_TYPE_EMPTY;
+       const char *str;
+       char name[128];
+       int result;
+
+       result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.SubjectAltName", &ext);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       result = asn1_write_value( ext, "", "NEW", 1);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       switch(type) {
+               case GNUTLS_SAN_DNSNAME:
+                       str = "dNSName";
+                       break;
+               case GNUTLS_SAN_RFC822NAME:
+                       str = "rfc822Name";
+                       break;
+               case GNUTLS_SAN_URI:
+                       str = "uniformResourceIdentifier";
+                       break;
+               case GNUTLS_SAN_IPADDRESS:
+                       str = "iPAddress";
+                       break;
+               default:
+                       gnutls_assert();
+                       return GNUTLS_E_INTERNAL_ERROR;
+       }
+
+       result = asn1_write_value( ext, "?LAST", str, 1);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       _gnutls_str_cpy( name, sizeof(name), "?LAST.");
+       _gnutls_str_cat( name, sizeof(name), str);
+
+       result = asn1_write_value(ext, name, data_string, strlen(data_string));
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               asn1_delete_structure(&ext);
+               return _gnutls_asn2err(result);
+       }
+
+       result = _gnutls_x509_der_encode( ext, "", der_ext, 0);
+
+       asn1_delete_structure(&ext);
+
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       return 0;
+}
index d9fb33dc5fb5a8f0e9aad74e4f2d836198abf5a7..e457fc231cab80bd235f94c70054c6d5e28376dd 100644 (file)
@@ -8,3 +8,5 @@ int _gnutls_x509_ext_extract_basicConstraints(int *CA, opaque * extnValue,
 int _gnutls_x509_crt_set_extension( gnutls_x509_crt cert, const char* extension_id, 
        const gnutls_datum* ext_data, unsigned int critical);
 int _gnutls_x509_ext_gen_basicConstraints(int CA, gnutls_datum* der_ext);
+int _gnutls_x509_ext_gen_subject_alt_name(gnutls_x509_subject_alt_name type, 
+       const char* data_string, gnutls_datum* der_ext);
index 952013324afaa7558534bf4556bfe7222921b34f..181aec9c0c9d2f9239fa5056cad919549962ee2b 100644 (file)
@@ -314,7 +314,6 @@ int _gnutls_x509_write_rsa_params( GNUTLS_MPI * params, int params_size,
        asn1_delete_structure(&spk);
 
        if (result != ASN1_SUCCESS) {
-               gnutls_assert();
                return _gnutls_asn2err(result);
        }
 
index 25715652a1e248fa8131e4670026b8e064bc93c2..181a3a858d833eeca48e3389b797caec90a92914 100644 (file)
@@ -58,30 +58,69 @@ static int _gnutls_verify_crl2(gnutls_x509_crl crl,
  * Returns true or false, if the issuer is a CA,
  * or not.
  */
-static int check_if_ca(gnutls_x509_crt cert,
-       gnutls_x509_crt issuer)
+static int check_if_ca(gnutls_x509_crt cert, gnutls_x509_crt issuer)
 {
+gnutls_datum cert_signed_data = { NULL, 0 };
+gnutls_datum issuer_signed_data = { NULL, 0 };
+gnutls_datum cert_signature = { NULL, 0 };
+gnutls_datum issuer_signature = { NULL, 0 };
+int result;
+
        /* Check if the issuer is the same with the
         * certificate. This is added in order for trusted
         * certificates to be able to verify themselves.
         */
-       if (cert->signed_data.size == issuer->signed_data.size) {
+
+       result = _gnutls_x509_get_signed_data( issuer->cert, "tbsCertificate", &issuer_signed_data);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _gnutls_x509_get_signed_data( cert->cert, "tbsCertificate", &cert_signed_data);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _gnutls_x509_get_signature( issuer->cert, "signature", &issuer_signature);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _gnutls_x509_get_signature( cert->cert, "signature", &cert_signature);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       if (cert_signed_data.size == issuer_signed_data.size) {
                if (
-                   (memcmp(cert->signed_data.data, issuer->signed_data.data,
-                       cert->signed_data.size) == 0) &&
-                   (cert->signature.size == issuer->signature.size) &&
-                   (memcmp(cert->signature.data, issuer->signature.data,
-                       cert->signature.size) == 0))
+                   (memcmp(cert_signed_data.data, issuer_signed_data.data,
+                       cert_signed_data.size) == 0) &&
+                   (cert_signature.size == issuer_signature.size) &&
+                   (memcmp(cert_signature.data, issuer_signature.data,
+                       cert_signature.size) == 0))
 
-                       return 1;
+                       result = 1;
+                       goto cleanup;
        }
 
        if (gnutls_x509_crt_get_ca_status(issuer, NULL) == 1) {
-               return 1;
+               result = 1;
+               goto cleanup;
        } else
                gnutls_assert();
 
-       return 0;
+       result = 0;
+
+cleanup:
+       _gnutls_free_datum( &cert_signed_data);
+       _gnutls_free_datum( &issuer_signed_data);
+       _gnutls_free_datum( &cert_signature);
+       _gnutls_free_datum( &issuer_signature);
+       return result;
 }
 
 
@@ -95,22 +134,27 @@ static int check_if_ca(gnutls_x509_crt cert,
 static
 int is_issuer(gnutls_x509_crt cert, gnutls_x509_crt issuer_cert)
 {
-       gnutls_const_datum dn1, dn2;
+       gnutls_datum dn1 = {NULL, 0}, dn2 = { NULL, 0 };
        int ret;
 
        ret = _gnutls_x509_crt_get_raw_issuer_dn( cert, &dn1);
        if (ret < 0) {
                gnutls_assert();
-               return ret;
+               goto cleanup;
        }
 
        ret = _gnutls_x509_crt_get_raw_dn( issuer_cert, &dn2);
        if (ret < 0) {
                gnutls_assert();
-               return ret;
+               goto cleanup;
        }
 
-       return _gnutls_x509_compare_raw_dn( &dn1, &dn2);
+       ret = _gnutls_x509_compare_raw_dn( &dn1, &dn2);
+       
+cleanup:
+       _gnutls_free_datum(&dn1);
+       _gnutls_free_datum(&dn2);       
+       return ret;
 
 }
 
@@ -145,10 +189,10 @@ static int _gnutls_verify_certificate2(gnutls_x509_crt cert,
                               gnutls_x509_crt *trusted_cas, int tcas_size, 
                               unsigned int flags)
 {
-/* CRL is ignored for now */
-
-       gnutls_x509_crt issuer;
-       int ret, issuer_version;
+gnutls_datum cert_signed_data = { NULL, 0 };
+gnutls_datum cert_signature = { NULL, 0 };
+gnutls_x509_crt issuer;
+int ret, issuer_version, result;
 
        if (tcas_size >= 1)
                issuer = find_issuer(cert, trusted_cas, tcas_size);
@@ -179,14 +223,33 @@ static int _gnutls_verify_certificate2(gnutls_x509_crt cert,
                }
        }
 
-       ret = _gnutls_x509_verify_signature(&cert->signed_data, &cert->signature, issuer);
+
+       result = _gnutls_x509_get_signed_data( cert->cert, "tbsCertificate", &cert_signed_data);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _gnutls_x509_get_signature( cert->cert, "signature", &cert_signature);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = _gnutls_x509_verify_signature(&cert_signed_data, &cert_signature, issuer);
        if (ret < 0) {
                gnutls_assert();
                /* error. ignore it */
                ret = 0;
        }
 
-       return ret;
+       result = ret;
+       
+cleanup:
+       _gnutls_free_datum( &cert_signed_data);
+       _gnutls_free_datum( &cert_signature);
+       
+       return result;
 }
 
 
@@ -602,13 +665,13 @@ int gnutls_x509_crl_verify( gnutls_x509_crl crl,
 static
 int is_crl_issuer(gnutls_x509_crl crl, gnutls_x509_crt issuer_cert)
 {
-       gnutls_const_datum dn1, dn2;
+       gnutls_datum dn1 = {NULL, 0}, dn2 = {NULL, 0};
        int ret;
 
        ret = _gnutls_x509_crl_get_raw_issuer_dn( crl, &dn1);
        if (ret < 0) {
                gnutls_assert();
-               return ret;
+               goto cleanup;
        }
 
        ret = _gnutls_x509_crt_get_raw_dn( issuer_cert, &dn2);
@@ -617,8 +680,13 @@ int is_crl_issuer(gnutls_x509_crl crl, gnutls_x509_crt issuer_cert)
                return ret;
        }
 
-       return _gnutls_x509_compare_raw_dn( &dn1, &dn2);
-
+       ret = _gnutls_x509_compare_raw_dn( &dn1, &dn2);
+       
+cleanup:
+       _gnutls_free_datum( &dn1);
+       _gnutls_free_datum( &dn2);
+       
+       return ret;
 }
 
 static inline
@@ -650,9 +718,10 @@ static int _gnutls_verify_crl2(gnutls_x509_crl crl,
                               unsigned int flags)
 {
 /* CRL is ignored for now */
-
-       gnutls_x509_crt issuer;
-       int ret;
+gnutls_datum crl_signed_data = { NULL, 0 };
+gnutls_datum crl_signature = { NULL, 0 };
+gnutls_x509_crt issuer;
+int ret, result;
 
        if (tcas_size >= 1)
                issuer = find_crl_issuer(crl, trusted_cas, tcas_size);
@@ -677,14 +746,33 @@ static int _gnutls_verify_crl2(gnutls_x509_crl crl,
                }
        }
 
-       ret = _gnutls_x509_verify_signature(&crl->signed_data, &crl->signature, issuer);
+       result = _gnutls_x509_get_signed_data( crl->crl, "tbsCertList", &crl_signed_data);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _gnutls_x509_get_signature( crl->crl, "signature", &crl_signature);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+
+       ret = _gnutls_x509_verify_signature(&crl_signed_data, &crl_signature, issuer);
        if (ret < 0) {
                gnutls_assert();
                /* error. ignore it */
                ret = 0;
        }
 
-       return ret;
+       result = ret;
+       
+cleanup:
+       _gnutls_free_datum( &crl_signed_data);
+       _gnutls_free_datum( &crl_signature);
+       
+       return result;
 }
 
 #endif
index 5a1a4cb0f2bc13ce23454efde004e077890b9653..bc17f7d06f6888736b363dbf50af316635c6bb68 100644 (file)
@@ -127,8 +127,6 @@ void gnutls_x509_crt_deinit(gnutls_x509_crt cert)
 
        if (cert->cert)
                asn1_delete_structure(&cert->cert);
-       _gnutls_free_datum(&cert->signed_data);
-       _gnutls_free_datum(&cert->signature);
 
        gnutls_free(cert);
 }
@@ -152,7 +150,6 @@ int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
        gnutls_x509_crt_fmt format)
 {
        int result = 0, need_free = 0;
-       int start, end, len, bits;
        gnutls_datum _data = { data->data, data->size };
        opaque *signature = NULL;
 
@@ -190,85 +187,6 @@ int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
                goto cleanup;
        }
 
-       /* Get the signed data
-        */
-       result = asn1_der_decoding_startEnd(cert->cert, _data.data, _data.size,
-                                           "tbsCertificate", &start,
-                                           &end);
-       if (result != ASN1_SUCCESS) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-
-
-       result =
-           _gnutls_set_datum(&cert->signed_data, &_data.data[start],
-                             end - start + 1);
-       if (result < 0) {
-               gnutls_assert();
-               goto cleanup;
-       }
-       
-       /* Read the signature 
-        */
-       bits = 0;
-       result = asn1_read_value( cert->cert, "signature", NULL, &bits);
-
-       if (result != ASN1_MEM_ERROR) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-
-       if (bits % 8 != 0) {
-               gnutls_assert();
-               result = GNUTLS_E_CERTIFICATE_ERROR;
-               goto cleanup;
-       }
-
-       len = bits/8;
-       signature = gnutls_malloc( len);
-       if (signature == NULL) {
-               gnutls_assert();
-               return GNUTLS_E_MEMORY_ERROR;
-       }
-               
-       /* read the bit string of the signature
-        */
-       bits = len;
-       result = asn1_read_value( cert->cert, "signature", signature,
-               &bits);
-
-       if (result != ASN1_SUCCESS) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-               
-               
-       if ((result=_gnutls_set_datum(&cert->signature, signature, len)) < 0) {
-               gnutls_assert();
-               goto cleanup;
-       }
-               
-       /* Read the signature algorithm. Note that parameters are not
-        * read. They will be read from the issuer's certificate if needed.
-        */
-               
-       result = asn1_read_value( cert->cert, "signatureAlgorithm.algorithm",
-               signature, &len);
-               
-       if (result != ASN1_SUCCESS) {
-               result = _gnutls_asn2err(result);
-               gnutls_assert();
-               goto cleanup;
-       }
-
-       cert->signature_algorithm = _gnutls_x509_oid2sign_algorithm( signature, NULL);
-
-       gnutls_free( signature);
-       signature = NULL;
 
        if (need_free) _gnutls_free_datum( &_data);
 
@@ -276,8 +194,6 @@ int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
 
       cleanup:
        gnutls_free( signature);
-       _gnutls_free_datum(&cert->signed_data);
-       _gnutls_free_datum(&cert->signature);
        if (need_free) _gnutls_free_datum( &_data);
        return result;
 }
@@ -419,9 +335,24 @@ int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt cert, const char* oid,
   **/
 int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt cert)
 {
-       return cert->signature_algorithm;
+       int result;
+       gnutls_datum sa;
 
-       return 0;
+       /* Read the signature algorithm. Note that parameters are not
+        * read. They will be read from the issuer's certificate if needed.
+        */
+       result = _gnutls_x509_read_value( cert->cert, "signatureAlgorithm.algorithm", &sa, 0);
+
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+       
+       result = _gnutls_x509_oid2sign_algorithm( sa.data, NULL);
+
+       _gnutls_free_datum( &sa);
+
+       return result;
 }
 
 /**
@@ -554,6 +485,7 @@ int gnutls_x509_crt_get_pk_algorithm( gnutls_x509_crt cert, unsigned int* bits)
   * This is specified in X509v3 Certificate Extensions. 
   * GNUTLS will return the Alternative name, or a negative
   * error code.
+  *
   * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if ret_size is not enough to hold the alternative 
   * name, or the type of alternative name if everything was ok. The type is 
   * one of the enumerated gnutls_x509_subject_alt_name.
@@ -804,11 +736,12 @@ int gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt cert, const char* oid,
 
 static
 int _gnutls_x509_crt_get_raw_dn2( gnutls_x509_crt cert,
-       const char* whom, gnutls_const_datum* start)
+       const char* whom, gnutls_datum* start)
 {
        ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
        int result, len1;
        int start1, end1;
+       gnutls_datum signed_data;
 
        /* get the issuer of 'cert'
         */
@@ -819,31 +752,41 @@ int _gnutls_x509_crt_get_raw_dn2( gnutls_x509_crt cert,
                return _gnutls_asn2err(result);
        }
 
-       result = asn1_der_decoding(&c2, cert->signed_data.data, cert->signed_data.size, NULL);
+       result = _gnutls_x509_get_signed_data( cert->cert, "tbsCertificate", &signed_data);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = asn1_der_decoding(&c2, signed_data.data, signed_data.size, NULL);
        if (result != ASN1_SUCCESS) {
                /* couldn't decode DER */
                gnutls_assert();
                asn1_delete_structure(&c2);
-               return _gnutls_asn2err(result);
+               result = _gnutls_asn2err(result);
+               goto cleanup;
        }
 
        result =
-           asn1_der_decoding_startEnd(c2, cert->signed_data.data, cert->signed_data.size,
+           asn1_der_decoding_startEnd(c2, signed_data.data, signed_data.size,
                   whom, &start1, &end1);
-       asn1_delete_structure(&c2);
 
        if (result != ASN1_SUCCESS) {
                gnutls_assert();
-               return _gnutls_asn2err(result);
+               result = _gnutls_asn2err(result);
+               goto cleanup;
        }
 
        len1 = end1 - start1 + 1;
 
-       start->data = &cert->signed_data.data[start1];
-       start->size = len1;
+       _gnutls_set_datum( start, &signed_data.data[start1], len1);
 
-       return 0;
+       result = 0;
 
+cleanup:
+       asn1_delete_structure(&c2);
+       _gnutls_free_datum( &signed_data);
+       return result;
 }
 
 /*-
@@ -858,7 +801,7 @@ int _gnutls_x509_crt_get_raw_dn2( gnutls_x509_crt cert,
   *
   -*/
 int _gnutls_x509_crt_get_raw_issuer_dn( gnutls_x509_crt cert,
-       gnutls_const_datum* start)
+       gnutls_datum* start)
 {
        return _gnutls_x509_crt_get_raw_dn2( cert, "issuer", start);
 }
@@ -875,7 +818,7 @@ int _gnutls_x509_crt_get_raw_issuer_dn( gnutls_x509_crt cert,
   *
   -*/
 int _gnutls_x509_crt_get_raw_dn( gnutls_x509_crt cert,
-       gnutls_const_datum * start)
+       gnutls_datum * start)
 {
        return _gnutls_x509_crt_get_raw_dn2( cert, "subject", start);
 }
@@ -1043,7 +986,7 @@ int gnutls_x509_crt_check_revocation(gnutls_x509_crt cert,
        opaque cert_serial[64];
        int serial_size, cert_serial_size;
        int ncerts, ret, i, j;
-       gnutls_const_datum dn1, dn2;
+       gnutls_datum dn1, dn2;
 
        for (j = 0; j < crl_list_length; j++) { /* do for all the crls */
 
index 457d8356778a6cf8ff5f2bd4be0d71bd279e1e9b..9ad73df8c453dc9b9b07408e56e5e79019a9a21c 100644 (file)
@@ -6,18 +6,11 @@
 
 typedef struct gnutls_x509_crl_int {
        ASN1_TYPE crl;
-       gnutls_datum signed_data; /* Holds the signed data of the CRL.
-                                  */
-       gnutls_datum signature;
-       gnutls_pk_algorithm signature_algorithm;
 } gnutls_x509_crl_int;
 
 typedef struct gnutls_x509_crt_int {
        ASN1_TYPE cert;
-       gnutls_datum signed_data; /* Holds the signed data of the CRL.
-                                  */
-       gnutls_datum signature;
-       gnutls_pk_algorithm signature_algorithm;
+       int use_extensions;
 } gnutls_x509_crt_int;
 
 
@@ -76,21 +69,21 @@ int gnutls_x509_crt_get_pk_algorithm( gnutls_x509_crt cert, unsigned int* bits);
 
 int _gnutls_x509_crt_cpy(gnutls_x509_crt dest, gnutls_x509_crt src);
 int _gnutls_x509_crt_get_raw_issuer_dn( gnutls_x509_crt cert,
-       gnutls_const_datum* start);
+       gnutls_datum* start);
 int _gnutls_x509_crt_get_raw_dn( gnutls_x509_crt cert,
-       gnutls_const_datum* start);
+       gnutls_datum* start);
 
 int gnutls_x509_crt_get_serial(gnutls_x509_crt cert, char* result, size_t* result_size);
 
-int _gnutls_x509_compare_raw_dn(const gnutls_const_datum * dn1,
-       const gnutls_const_datum * dn2);
+int _gnutls_x509_compare_raw_dn(const gnutls_datum * dn1,
+       const gnutls_datum * dn2);
 
 int gnutls_x509_crt_check_revocation(gnutls_x509_crt cert, gnutls_x509_crl * crl_list, int crl_list_length);
 
 
 int _gnutls_x509_crl_cpy(gnutls_x509_crl dest, gnutls_x509_crl src);
 int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
-       gnutls_const_datum* dn);
+       gnutls_datum* dn);
 int gnutls_x509_crl_get_certificate_count(gnutls_x509_crl crl);
 int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index,
                                    unsigned char *serial,
@@ -134,5 +127,4 @@ int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey key,
 int gnutls_x509_privkey_export( gnutls_x509_privkey key,
        gnutls_x509_crt_fmt format, unsigned char* output_data, size_t* output_data_size);
 
-
 #endif
index a35d4882a200c278321164f4e2f6c3f05a35d8e0..139729a54be9b2f876d9dd1068e64e20d3bd144b 100644 (file)
@@ -221,6 +221,59 @@ gnutls_datum der_data;
                return result;
        }
 
+       crt->use_extensions = 1;
+
+       return 0;
+}
+
+/**
+  * gnutls_x509_crt_set_subject_alt_name - This function will set the subject Alternative Name
+  * @crt: should contain a gnutls_x509_crt structure
+  * @type: is one of the gnutls_x509_subject_alt_name enumerations
+  * @data_string: The data to be set
+  *
+  * This function will set the subject alternative name certificate extension. 
+  *
+  * On success zero is returned.
+  *
+  **/
+int gnutls_x509_crt_set_subject_alternative_name(gnutls_x509_crt crt, gnutls_x509_subject_alt_name type,
+       const char* data_string)
+{
+int result;
+gnutls_datum der_data;
+gnutls_datum dnsname;
+unsigned int critical;
+
+       /* Check if the extension already exists.
+        */
+       result = _gnutls_x509_crt_get_extension(crt, "2.5.29.17", 0, &dnsname, &critical);
+
+       if (result >= 0) _gnutls_free_datum( &dnsname);
+       if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       /* generate the extension.
+        */
+       result = _gnutls_x509_ext_gen_subject_alt_name( type, data_string, &der_data);
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       result = _gnutls_x509_crt_set_extension( crt, "2.5.29.17", &der_data, 0);
+
+       _gnutls_free_datum( &der_data);
+
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       crt->use_extensions = 1;
+
        return 0;
 }
 
@@ -398,22 +451,15 @@ int gnutls_x509_crt_set_serial(gnutls_x509_crt cert, const unsigned char* serial
  */
 static void disable_optional_stuff( gnutls_x509_crt cert)
 {
-int ret, len = 1;
-opaque tmp;
 
-       ret = asn1_read_value( cert->cert, "tbsCertificate.issuerUniqueID", &tmp, &len);
-       if (ret == ASN1_VALUE_NOT_FOUND)
-               asn1_write_value( cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
+       asn1_write_value( cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
 
-       len = 1;
-       ret = asn1_read_value( cert->cert, "tbsCertificate.subjectUniqueID", &tmp, &len);
-       if (ret == ASN1_VALUE_NOT_FOUND)
-               asn1_write_value( cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
+       asn1_write_value( cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
 
-       len = 1;
-       ret = asn1_read_value( cert->cert, "tbsCertificate.extensions", &tmp, &len);
-       if (ret == ASN1_VALUE_NOT_FOUND)
+       if (cert->use_extensions == 0) {
+               _gnutls_x509_log( "Disabling X.509 extensions.\n");
                asn1_write_value( cert->cert, "tbsCertificate.extensions", NULL, 0);
+       }
 
        return;
 }