]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added some stuff needed in PKCS#10 certificate request generation. Some other fixes...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 14 Mar 2003 12:53:16 +0000 (12:53 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 14 Mar 2003 12:53:16 +0000 (12:53 +0000)
22 files changed:
lib/Makefile.am
lib/auth_cert.c
lib/auth_dhe.c
lib/auth_rsa.c
lib/auth_rsa_export.c
lib/gnutls_pk.c
lib/gnutls_pk.h
lib/gnutls_sig.c
lib/gnutls_sig.h
lib/pkix.asn
lib/pkix_asn1_tab.c
lib/x509/Makefile.am
lib/x509/crl.c
lib/x509/crq.c [new file with mode: 0644]
lib/x509/crq.h [new file with mode: 0644]
lib/x509/pkcs7.c
lib/x509/privkey.c
lib/x509/sign.c [new file with mode: 0644]
lib/x509/sign.h [new file with mode: 0644]
lib/x509/verify.c
lib/x509/x509.c
lib/x509/x509.h

index ff45038379bef0cd8f7fb323cfeb6963513baf45..768930d466ec93f117d17edcdf6e9fe0542ef62d 100644 (file)
@@ -49,7 +49,7 @@ libgnutls_la_SOURCES = $(COBJECTS)
 
 libgnutls_la_LIBADD = $(MINITASN1_OBJECTS) x509/dn.lo x509/crl.lo x509/common.lo \
        x509/x509.lo x509/pkcs7.lo x509/extensions.lo x509/compat.lo x509/verify.lo \
-       x509/mpi.lo x509/privkey.lo
+       x509/mpi.lo x509/privkey.lo x509/crq.lo x509/sign.lo
 
 libgnutls_la_LDFLAGS = $(LIBASN1_LINK) $(LIBGCRYPT_LIBS) \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) #-export-symbols gnutls.sym
index c20be5aff9838715c3143b42df927a0637d743e4..37bdf5bc61d1408f16f998b77e2fcfe6a0900305 100644 (file)
@@ -1055,7 +1055,7 @@ int _gnutls_gen_cert_client_cert_vrfy(gnutls_session session,
 
        if (apr_pkey != NULL) {
                if ((ret =
-                    _gnutls_generate_sig_from_hdata(session,
+                    _gnutls_tls_sign_hdata(session,
                                                     &apr_cert_list[0],
                                                     apr_pkey,
                                                     &signature)) < 0) {
index 4e7323297aa2d881992b2e40c0abffccb49bf410..d495311c53269ff17a62957745cac6215213b56e 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
+ *  Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
  *
- * This file is part of GNUTLS.
+ *  This file is part of GNUTLS.
  *
  *  The GNUTLS library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public   
@@ -141,7 +141,7 @@ static int gen_dhe_server_kx(gnutls_session session, opaque ** data)
 
        if (apr_pkey != NULL) {
                if ((ret =
-                    _gnutls_generate_sig_params(session, &apr_cert_list[0],
+                    _gnutls_tls_sign_params(session, &apr_cert_list[0],
                                                 apr_pkey, &ddata,
                                                 &signature)) < 0) {
                        gnutls_assert();
index 1c1ec48a081507b6edd7b4152c72a7d43de61a78..961adde5d75d7c60d2d02f343f28b4d65ce7021b 100644 (file)
@@ -306,7 +306,7 @@ int _gnutls_gen_rsa_client_kx(gnutls_session session, opaque ** data)
        }
 
        if ((ret =
-            _gnutls_pkcs1_rsa_encrypt(&sdata, session->key->key,
+            _gnutls_pkcs1_rsa_encrypt(&sdata, &session->key->key,
                                       params, params_len, 2)) < 0) {
                gnutls_assert();
                return ret;
index 6445fd844fcb7367ea66ca5941e93371d27be93c..b57def2cff0c8c12613cbfd93ef9e3a64a83be39 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
+ *  Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
  *
- * This file is part of GNUTLS.
+ *  This file is part of GNUTLS.
  *
  *  The GNUTLS library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public   
@@ -148,7 +148,7 @@ static int gen_rsa_export_server_kx(gnutls_session session, opaque ** data)
 
        if (apr_pkey != NULL) {
                if ((ret =
-                    _gnutls_generate_sig_params(session, &apr_cert_list[0],
+                    _gnutls_tls_sign_params(session, &apr_cert_list[0],
                                                 apr_pkey, &ddata,
                                                 &signature)) < 0) {
                        gnutls_assert();
index 1b538301e3b86e1e302c5bd4863b0b342e8ab6ff..7aa969f2d7d1fce9d3d7fa5dca0b6fdce376312f 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos
+ *  Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos
  *
- * This file is part of GNUTLS.
+ *  This file is part of GNUTLS.
  *
  *  The GNUTLS library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public   
@@ -42,7 +42,7 @@ static int _gnutls_pk_decrypt(int algo, GNUTLS_MPI * resarr, GNUTLS_MPI data, GN
  * params is modulus, public exp.
  */
 int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext,
-                             gnutls_datum plaintext, GNUTLS_MPI* params,
+                             const gnutls_datum *plaintext, GNUTLS_MPI* params,
                              uint params_len,
                              uint btype)
 {
@@ -57,7 +57,7 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext,
        k = mod_bits / 8;
        if ( mod_bits % 8 != 0) k++;
 
-       if (plaintext.size > k - 11) {
+       if (plaintext->size > k - 11) {
                gnutls_assert();
                return GNUTLS_E_PK_ENCRYPTION_FAILED;
        }
@@ -74,7 +74,7 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext,
 
        edata[0] = 0;
        edata[1] = btype;
-       psize = k - 3 - plaintext.size;
+       psize = k - 3 - plaintext->size;
 
        ps = &edata[2];
        switch (btype) {
@@ -111,7 +111,7 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext,
        }
 
        ps[psize] = 0;
-       memcpy(&ps[psize + 1], plaintext.data, plaintext.size);
+       memcpy(&ps[psize + 1], plaintext->data, plaintext->size);
 
        if (_gnutls_mpi_scan(&m, edata, &k) != 0) {
                gnutls_assert();
index 30483992ad76b575df664a4db1e823ab79fbc638..d3b14315e6e7190f9c12c1d2e6c545345917490e 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef GNUTLS_PK_H
 # define GNUTLS_PK_H
 
-int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, gnutls_datum plaintext,
+int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, const gnutls_datum *plaintext,
                      MPI * params, uint params_len, uint btype);
 int _gnutls_dsa_sign(gnutls_datum * signature, const gnutls_datum *plaintext,
                      MPI *params, uint params_len);
index a70d1fd2add9b969cf83466d6c4b6762a9225c5e..07f4b80825f389c608d6e96ea5988930013f11a7 100644 (file)
 #include <gnutls_sig.h>
 
 
-int _gnutls_generate_sig( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
+static
+int _gnutls_tls_sign( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
 
 
 /* Generates a signature of all the previous sent packets in the 
  * handshake procedure.
  */
-int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum *signature) {
+int _gnutls_tls_sign_hdata( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum *signature) {
 gnutls_datum dconcat;
 int ret;
 opaque concat[36];
@@ -77,7 +78,7 @@ GNUTLS_MAC_HANDLE td_sha;
                        gnutls_assert();
                        return GNUTLS_E_INTERNAL_ERROR;
        }
-       ret = _gnutls_generate_sig( cert, pkey, &dconcat, signature);
+       ret = _gnutls_tls_sign( cert, pkey, &dconcat, signature);
        if (ret < 0)
                gnutls_assert();
        
@@ -88,7 +89,7 @@ GNUTLS_MAC_HANDLE td_sha;
 /* Generates a signature of all the random data and the parameters.
  * Used in DHE_* ciphersuites.
  */
-int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum* params, gnutls_datum *signature) 
+int _gnutls_tls_sign_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum* params, gnutls_datum *signature) 
 {
 gnutls_datum dconcat;
 int ret;
@@ -135,7 +136,7 @@ opaque concat[36];
                        gnutls_assert();
                        return GNUTLS_E_INTERNAL_ERROR;
        }
-       ret = _gnutls_generate_sig( cert, pkey, &dconcat, signature);
+       ret = _gnutls_tls_sign( cert, pkey, &dconcat, signature);
        if (ret < 0)
                gnutls_assert();
        
@@ -148,10 +149,9 @@ opaque concat[36];
  * Cert is the certificate of the corresponding private key. It is only checked if
  * it supports signing.
  */
-int _gnutls_generate_sig( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature)
+static
+int _gnutls_tls_sign( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature)
 {
-int ret;
-gnutls_datum tmpdata;
 
        /* If our certificate supports signing
         */
@@ -163,14 +163,25 @@ gnutls_datum tmpdata;
                        return GNUTLS_E_KEY_USAGE_VIOLATION;
                }
 
-       tmpdata.data = hash_concat->data;
-       tmpdata.size = hash_concat->size;
+       return _gnutls_sign( pkey->pk_algorithm, pkey->params, pkey->params_size, 
+               hash_concat, signature);
+               
+}
+
+
+/* This will create a PKCS1 or DSA signature, using the given parameters, and the
+ * given data. The output will be allocated and be put in signature.
+ */
+int _gnutls_sign( gnutls_pk_algorithm algo, GNUTLS_MPI* params, int params_size, 
+       const gnutls_datum* data, gnutls_datum *signature)
+{
+int ret;
 
-       switch(pkey->pk_algorithm) {
+       switch(algo) {
                case GNUTLS_PK_RSA:
                        /* encrypt */
-                       if ((ret=_gnutls_pkcs1_rsa_encrypt( signature, tmpdata, pkey->params, 
-                               pkey->params_size, 1)) < 0) {
+                       if ((ret=_gnutls_pkcs1_rsa_encrypt( signature, data, params, 
+                               params_size, 1)) < 0) {
                             gnutls_assert();
                             return ret;
                        }
@@ -178,8 +189,8 @@ gnutls_datum tmpdata;
                        break;
                case GNUTLS_PK_DSA:
                        /* sign */
-                       if ((ret=_gnutls_dsa_sign( signature, &tmpdata, pkey->params, 
-                               pkey->params_size)) < 0) {
+                       if ((ret=_gnutls_dsa_sign( signature, data, params, 
+                               params_size)) < 0) {
                             gnutls_assert();
                             return ret;
                        }
@@ -190,14 +201,14 @@ gnutls_datum tmpdata;
                        break;
        }
 
-
-
        return 0;
 }
 
 
-
-int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *hash_concat, gnutls_datum *signature) {
+static
+int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *hash_concat, 
+       gnutls_datum *signature) 
+{
        int ret;
        gnutls_datum vdata;
 
index e839c38d8879851dd7eaf34e1ea73d3a3792abfd..30feba7b436b3501e68dd3b5b9fca025f1c75160 100644 (file)
@@ -3,9 +3,11 @@
 # include <auth_cert.h>
 
 gnutls_certificate_status gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
-int _gnutls_generate_sig_from_hdata( gnutls_session session, gnutls_cert* cert, gnutls_privkey *pkey, gnutls_datum *signature);
-int _gnutls_generate_sig_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey *pkey, gnutls_datum* params, gnutls_datum *signature);
+int _gnutls_tls_sign_hdata( gnutls_session session, gnutls_cert* cert, gnutls_privkey *pkey, gnutls_datum *signature);
+int _gnutls_tls_sign_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey *pkey, gnutls_datum* params, gnutls_datum *signature);
 int _gnutls_verify_sig_hdata( gnutls_session session, gnutls_cert *cert, gnutls_datum* signature);
 int _gnutls_verify_sig_params( gnutls_session session, gnutls_cert *cert, const gnutls_datum* params, gnutls_datum* signature);
+int _gnutls_sign( gnutls_pk_algorithm algo, GNUTLS_MPI* params, int params_size, 
+       const gnutls_datum* data, gnutls_datum *signature);
 
 #endif
index 6cf70a7c82e58c7d8db1a74fddf0f2924af9bb98..e628b190ce79b996d03400fcc59f5984ffc29e7a 100644 (file)
@@ -980,4 +980,23 @@ CertificateSet ::= SET OF CertificateChoices
 SignerInfos ::= SET OF ANY -- this is not correct but we don't use it
  -- anyway
 
+
+-- BEGIN of RFC2986
+
+-- Certificate requests
+CertificationRequestInfo ::= SEQUENCE {
+     version       INTEGER { v1(0) },
+     subject       Name,
+     subjectPKInfo SubjectPublicKeyInfo,
+     attributes    [0] Attributes
+}
+
+Attributes ::= SET OF Attribute
+
+CertificationRequest ::= SEQUENCE {
+     certificationRequestInfo CertificationRequestInfo,
+     signatureAlgorithm AlgorithmIdentifier,
+     signature          BIT STRING
+}
+
 END
index 2958e8f871329b1becf50dfbec2f44ef89b90ee5..e1d489c3c0e90bd5e1f2f87944bd659931ef83fb 100644 (file)
@@ -896,7 +896,20 @@ const ASN1_ARRAY_TYPE pkix_asn1_tab[]={
   {"certificate",2,"Certificate"},
   {"CertificateSet",1610612751,0},
   {0,2,"CertificateChoices"},
-  {"SignerInfos",536870927,0},
+  {"SignerInfos",1610612751,0},
   {0,13,0},
+  {"CertificationRequestInfo",1610612741,0},
+  {"version",1610874883,0},
+  {"v1",1,"0"},
+  {"subject",1073741826,"Name"},
+  {"subjectPKInfo",1073741826,"SubjectPublicKeyInfo"},
+  {"attributes",536879106,"Attributes"},
+  {0,4104,"0"},
+  {"Attributes",1610612751,0},
+  {0,2,"Attribute"},
+  {"CertificationRequest",536870917,0},
+  {"certificationRequestInfo",1073741826,"CertificationRequestInfo"},
+  {"signatureAlgorithm",1073741826,"AlgorithmIdentifier"},
+  {"signature",6,0},
   {0,0,0}
 };
index 8165cfc3bdc8be4ccf0b32a31e4e94a402062c1c..a84013b1c87fc2eabae75623a7e87ae2c7e83772 100644 (file)
@@ -1,11 +1,12 @@
 INCLUDES = -I../ -I../minitasn1/ -I../../includes/
 EXTRA_DIST = dn.h common.h x509.h extensions.h pkcs7.h \
-       x509-api.tex compat.h verify.h mpi.h
+       x509-api.tex compat.h verify.h mpi.h crq.h sign.h
 
 noinst_LTLIBRARIES = libx509.la
 
-COBJECTS = crl.c dn.c common.c x509.c extensions.c \
-       pkcs7.c xml.c rfc2818_hostname.c verify.c mpi.c privkey.c
+COBJECTS = crl.c dn.c common.c x509.c extensions.c crq.c \
+       pkcs7.c xml.c rfc2818_hostname.c verify.c mpi.c privkey.c \
+       sign.c
 
 COMPAT_OBJECTS = compat.c
 
index 52506b182a4255aef8770338c0535fa6d023bb89..436f3832a710169efd6b081c07a4b0a4e7c78d7c 100644 (file)
@@ -44,7 +44,13 @@ int gnutls_x509_crl_init(gnutls_x509_crl * crl)
        *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
 
        if (*crl) {
-               (*crl)->crl = ASN1_TYPE_EMPTY;
+               int result = asn1_create_element(_gnutls_get_pkix(),
+                                    "PKIX1.CertificateList",
+                                    &(*crl)->crl);
+               if (result != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       return _gnutls_asn2err(result);
+               }
                return 0;       /* success */
        }
        return GNUTLS_E_MEMORY_ERROR;
@@ -110,15 +116,6 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
                need_free = 1;
        }
 
-       crl->crl = ASN1_TYPE_EMPTY;
-
-       result = asn1_create_element(_gnutls_get_pkix(),
-                                    "PKIX1.CertificateList",
-                                    &crl->crl);
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               return _gnutls_asn2err(result);
-       }
 
        result =
            asn1_der_decoding(&crl->crl, _data.data, _data.size, NULL);
@@ -205,8 +202,6 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
        return 0;
 
       cleanup:
-       if (crl->crl)
-               asn1_delete_structure(&crl->crl);
        _gnutls_free_datum(&crl->signed_data);
        _gnutls_free_datum(&crl->signature);
        if (need_free)
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
new file mode 100644 (file)
index 0000000..5fe2d15
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *  Copyright (C) 2003 Nikos Mavroyanopoulos
+ *
+ *  This file is part of GNUTLS.
+ *
+ *  The GNUTLS library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public   
+ *  License as published by the Free Software Foundation; either 
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+/* This file contains functions to handle PKCS #10 certificate requests.
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_datum.h>
+#include <gnutls_global.h>
+#include <gnutls_errors.h>
+#include <common.h>
+#include <gnutls_x509.h>
+#include <x509_b64.h>
+#include <crq.h>
+#include <dn.h>
+#include <extensions.h>
+#include <libtasn1.h>
+#include <gnutls_ui.h>
+
+/**
+  * gnutls_x509_crq_init - This function initializes a gnutls_x509_crq structure
+  * @crq: The structure to be initialized
+  *
+  * This function will initialize a PKCS10 certificate request structure. 
+  *
+  * Returns 0 on success.
+  *
+  **/
+int gnutls_x509_crq_init(gnutls_x509_crq * crq)
+{
+       *crq = gnutls_calloc( 1, sizeof(gnutls_x509_crq_int));
+
+       if (*crq) {
+               int result = asn1_create_element(_gnutls_get_pkix(),
+                                    "PKIX1.CertificationRequest",
+                                    &((*crq)->crq));
+               if (result != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       return _gnutls_asn2err(result);
+               }
+               return 0;               /* success */
+       }
+       return GNUTLS_E_MEMORY_ERROR;
+}
+
+/**
+  * gnutls_x509_crq_deinit - This function deinitializes memory used by a gnutls_x509_crq structure
+  * @crq: The structure to be initialized
+  *
+  * This function will deinitialize a CRL structure. 
+  *
+  **/
+void gnutls_x509_crq_deinit(gnutls_x509_crq crq)
+{
+       if (crq->crq)
+               asn1_delete_structure(&crq->crq);
+
+       gnutls_free(crq);
+}
+
+#define PEM_CRQ "CERTIFICATE REQUEST"
+
+/**
+  * gnutls_x509_crq_import - This function will import a DER or PEM encoded Certificate request
+  * @crq: The structure to store the parsed certificate request.
+  * @data: The DER or PEM encoded certificate.
+  * @format: One of DER or PEM
+  *
+  * This function will convert the given DER or PEM encoded Certificate
+  * to the native gnutls_x509_crq format. The output will be stored in 'cert'.
+  *
+  * If the Certificate is PEM encoded it should have a header of "CERTIFICATE REQUEST".
+  *
+  * Returns 0 on success.
+  *
+  **/
+int gnutls_x509_crq_import(gnutls_x509_crq crq, const gnutls_datum * data,
+       gnutls_x509_crt_fmt format)
+{
+       int result = 0, need_free = 0;
+       gnutls_datum _data = { data->data, data->size };
+
+       /* If the Certificate is in PEM format then decode it
+        */
+       if (format == GNUTLS_X509_FMT_PEM) {
+               opaque *out;
+               
+               /* Try the first header */
+               result = _gnutls_fbase64_decode(PEM_CRQ, data->data, data->size,
+                       &out);
+
+               if (result <= 0) {
+                       if (result==0) result = GNUTLS_E_INTERNAL_ERROR;
+                       gnutls_assert();
+                       return result;
+               }
+               
+               _data.data = out;
+               _data.size = result;
+               
+               need_free = 1;
+       }
+
+       result = asn1_der_decoding(&crq->crq, _data.data, _data.size, NULL);
+       if (result != ASN1_SUCCESS) {
+               result = _gnutls_asn2err(result);
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       if (need_free) _gnutls_free_datum( &_data);
+
+       return 0;
+
+      cleanup:
+       if (need_free) _gnutls_free_datum( &_data);
+       return result;
+}
+
+
+
+/**
+  * gnutls_x509_crq_get_dn - This function returns the Certificate request subject's distinguished name
+  * @crq: should contain a gnutls_x509_crq structure
+  * @buf: a pointer to a structure to hold the name (may be null)
+  * @sizeof_buf: initialy holds the size of 'buf'
+  *
+  * This function will copy the name of the Certificate request subject in the provided buffer. The name 
+  * will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253.
+  *
+  * If buf is null then only the size will be filled.
+  *
+  * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
+  * in that case the sizeof_buf will be updated with the required size.
+  * On success zero is returned.
+  *
+  **/
+int gnutls_x509_crq_get_dn(gnutls_x509_crq crq, char *buf,
+                                        int *sizeof_buf)
+{
+       if (sizeof_buf == 0 || crq == NULL) {
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+       
+       return _gnutls_x509_parse_dn( crq->crq, "certificationRequestInfo.subject.rdnSequence",
+               buf, sizeof_buf);
+
+               
+}
+
+/**
+  * gnutls_x509_crq_get_dn_by_oid - This function returns the Certificate request subject's distinguished name
+  * @crq: should contain a gnutls_x509_crq structure
+  * @oid: holds an Object Identified in null terminated string
+  * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
+  * @buf: a pointer to a structure to hold the name (may be null)
+  * @sizeof_buf: initialy holds the size of 'buf'
+  *
+  * This function will extract the part of the name of the Certificate request subject, specified
+  * by the given OID. The output will be encoded as described in RFC2253.
+  *
+  * Some helper macros with popular OIDs can be found in gnutls/x509.h
+  *
+  * If buf is null then only the size will be filled.
+  *
+  * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
+  * in that case the sizeof_buf will be updated with the required size.
+  * On success zero is returned.
+  *
+  **/
+int gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq crq, const char* oid, 
+       int indx, char *buf, int *sizeof_buf)
+{
+       if (sizeof_buf == 0 || crq == NULL) {
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+       
+       return _gnutls_x509_parse_dn_oid( crq->crq, "certificationRequestInfo.subject.rdnSequence", oid,
+               indx, buf, sizeof_buf);
+
+               
+}
+
+/**
+  * gnutls_x509_crq_export - This function will export the generated certificate request
+  * @crq: Holds the request
+  * @format: the format of output params. One of PEM or DER.
+  * @output_data: will contain a certificate request PEM or DER encoded
+  * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
+  *
+  * This function will export the certificate request to a PKCS10
+  *
+  * If the buffer provided is not long enough to hold the output, then
+  * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
+  *
+  * If the structure is PEM encoded, it will have a header
+  * of "BEGIN CERTIFICATE REQUEST".
+  *
+  * In case of failure a negative value will be returned, and
+  * 0 on success.
+  *
+  **/
+int gnutls_x509_crq_export( gnutls_x509_crq crq,
+       gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size)
+{
+       return _gnutls_x509_export_int( crq->crq, format, PEM_CRQ, *output_data_size,
+               output_data, output_data_size);
+}
diff --git a/lib/x509/crq.h b/lib/x509/crq.h
new file mode 100644 (file)
index 0000000..58a14cf
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef CRL_H
+# define CRL_H
+
+typedef struct gnutls_x509_crq_int {
+       ASN1_TYPE crq;
+} gnutls_x509_crq_int;
+
+typedef struct gnutls_x509_crq_int *gnutls_x509_crq;
+
+int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt cert, const char* oid, 
+       int indx, char *buf, int *sizeof_buf);
+
+int gnutls_x509_crq_init(gnutls_x509_crq * crq);
+void gnutls_x509_crq_deinit(gnutls_x509_crq crq);
+
+int gnutls_x509_crq_import(gnutls_x509_crq crq, const gnutls_datum * data,
+       gnutls_x509_crt_fmt format);
+
+#endif
index 67166ba16f070edba5ab5d658dbb4ac5c310ed47..8f7d7591071370d7a627636278e5cbc149b43070 100644 (file)
@@ -19,6 +19,9 @@
  *
  */
 
+/* Functions that relate on PKCS7 certificate lists parsing.
+ */
+
 #include <libtasn1.h>
 #include <gnutls_int.h>
 #include <gnutls_datum.h>
@@ -33,8 +36,7 @@
   * gnutls_pkcs7_init - This function initializes a gnutls_pkcs7 structure
   * @pkcs7: The structure to be initialized
   *
-  * This function will initialize a PKCS7 structure. PKCS7 stands for
-  * Certificate Revocation List.
+  * This function will initialize a PKCS7 structure. 
   *
   * Returns 0 on success.
   *
@@ -44,7 +46,13 @@ int gnutls_pkcs7_init(gnutls_pkcs7 * pkcs7)
        *pkcs7 = gnutls_calloc( 1, sizeof(gnutls_pkcs7_int));
 
        if (*pkcs7) {
-               (*pkcs7)->pkcs7 = ASN1_TYPE_EMPTY;
+               int result = asn1_create_element(_gnutls_get_pkix(),
+                                    "PKIX1.ContentInfo",
+                                    &(*pkcs7)->pkcs7);
+               if (result != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       return _gnutls_asn2err(result);
+               }
                return 0;               /* success */
        }
        return GNUTLS_E_MEMORY_ERROR;
@@ -74,7 +82,7 @@ void gnutls_pkcs7_deinit(gnutls_pkcs7 pkcs7)
   * This function will convert the given DER or PEM encoded PKCS7
   * to the native gnutls_pkcs7 format. The output will be stored in 'pkcs7'.
   *
-  * If the PKCS7 is PEM encoded it should have a header of "X509 PKCS7".
+  * If the PKCS7 is PEM encoded it should have a header of "PKCS7".
   *
   * Returns 0 on success.
   *
@@ -105,15 +113,6 @@ int gnutls_pkcs7_import(gnutls_pkcs7 pkcs7, const gnutls_datum * data,
                need_free = 1;
        }
 
-       pkcs7->pkcs7 = ASN1_TYPE_EMPTY;
-
-       result = asn1_create_element(_gnutls_get_pkix(),
-                                    "PKIX1.ContentInfo",
-                                    &pkcs7->pkcs7);
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               return _gnutls_asn2err(result);
-       }
 
        result = asn1_der_decoding(&pkcs7->pkcs7, _data.data, _data.size, NULL);
        if (result != ASN1_SUCCESS) {
@@ -127,8 +126,6 @@ int gnutls_pkcs7_import(gnutls_pkcs7 pkcs7, const gnutls_datum * data,
        return 0;
 
       cleanup:
-       if (pkcs7->pkcs7)
-               asn1_delete_structure(&pkcs7->pkcs7);
        if (need_free) _gnutls_free_datum( &_data);
        return result;
 }
index 2e6f6880c1b9a3416fea7056ca227b8d8446d813..ad3971d2363ad85edcb2f7fba9077a9b705459a7 100644 (file)
@@ -255,8 +255,8 @@ static ASN1_TYPE decode_dsa_key( const gnutls_datum* raw_key,
 }
 
 
-#define PEM_KEY_DSA "DSA PRIVATE"
-#define PEM_KEY_RSA "RSA PRIVATE"
+#define PEM_KEY_DSA "DSA PRIVATE KEY"
+#define PEM_KEY_RSA "RSA PRIVATE KEY"
 
 /**
   * gnutls_x509_privkey_import - This function will import a DER or PEM encoded Certificate
@@ -478,67 +478,16 @@ int gnutls_x509_privkey_get_pk_algorithm( gnutls_x509_privkey key)
 int gnutls_x509_privkey_export( gnutls_x509_privkey key,
        gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size)
 {
-       int result;
-       
-       if (format == GNUTLS_X509_FMT_DER) {
-               if ((result=asn1_der_coding( key->key, "", output_data, output_data_size, NULL)) != ASN1_SUCCESS) {
-                       gnutls_assert();
-                       
-                       if (result == ASN1_MEM_ERROR)
-                               return GNUTLS_E_SHORT_MEMORY_BUFFER;
-
-                       return _gnutls_asn2err(result);
-               }
-
-       } else { /* PEM */
-               opaque tmp[5*1024];
-               opaque *out;
-               int len;
-               char * msg;
-               
-               len = sizeof(tmp) - 1;
-               if ((result=asn1_der_coding( key->key, "", tmp, &len, NULL)) != ASN1_SUCCESS) {
-                       gnutls_assert();
-                       return _gnutls_asn2err(result);
-               }
-
-               if (key->pk_algorithm == GNUTLS_PK_RSA)
-                       msg = "RSA PRIVATE KEY";
-               else if (key->pk_algorithm == GNUTLS_PK_DSA)
-                       msg = "DSA PRIVATE KEY";
-               else msg = NULL;
-
-               result = _gnutls_fbase64_encode( msg,
-                                               tmp, len, &out);
-
-               if (result < 0) {
-                       gnutls_assert();
-                       return result;
-               }
-
-               if (result == 0) {      /* oooops */
-                       gnutls_assert();
-                       return GNUTLS_E_INTERNAL_ERROR;
-               }
-
-               if (result + 1 > *output_data_size) {
-                       gnutls_assert();
-                       gnutls_free(out);
-                       *output_data_size = result;
-                       return GNUTLS_E_SHORT_MEMORY_BUFFER;
-               }
-
-               *output_data_size = result;
-               
-               if (output_data) {
-                       memcpy( output_data, out, result);
-                       output_data[result] = 0;
-               }
-               gnutls_free( out);
+       char * msg;
                
-       }
-
-       return 0;
+       if (key->pk_algorithm == GNUTLS_PK_RSA)
+               msg = PEM_KEY_RSA;
+       else if (key->pk_algorithm == GNUTLS_PK_DSA)
+               msg = PEM_KEY_DSA;
+       else msg = NULL;
+
+       return _gnutls_x509_export_int( key->key, format, msg, *output_data_size,
+               output_data, output_data_size);
 }
 
 /**
diff --git a/lib/x509/sign.c b/lib/x509/sign.c
new file mode 100644 (file)
index 0000000..78af411
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ *  Copyright (C) 2003 Nikos Mavroyanopoulos <nmav@hellug.gr>
+ *
+ *  This file is part of GNUTLS.
+ *
+ *  The GNUTLS library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public   
+ *  License as published by the Free Software Foundation; either 
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+/* All functions which relate to X.509 certificate signing stuff are
+ * included here
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <gnutls_cert.h>
+#include <libtasn1.h>
+#include <gnutls_global.h>
+#include <gnutls_num.h>                /* GMAX */
+#include <gnutls_sig.h>
+#include <gnutls_str.h>
+#include <gnutls_datum.h>
+#include <dn.h>
+#include <x509.h>
+#include <mpi.h>
+#include <sign.h>
+#include <verify.h>
+
+/* Writes the digest information and the digest in a DER encoded
+ * structure. The digest info is allocated and stored into the info structure.
+ */
+static int encode_ber_digest_info( gnutls_mac_algorithm hash, 
+       const gnutls_datum* digest, gnutls_datum *info) 
+{
+ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
+int result;
+char* algo;
+
+       switch(hash) {
+               case GNUTLS_MAC_MD5:
+                       algo = OID_MD5;
+                       break;
+               case GNUTLS_MAC_MD2:
+                       algo = OID_MD2;
+                       break;
+               case GNUTLS_MAC_SHA:
+                       algo = OID_SHA1;
+                       break;
+               default:
+                       return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+       }
+
+       if ((result=asn1_create_element( _gnutls_get_gnutls_asn(), 
+               "GNUTLS.DigestInfo", &dinfo))!=ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+               
+       result =
+           asn1_write_value( dinfo, "digestAlgorithm.algorithm", algo, 1);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               asn1_delete_structure(&dinfo);
+               return _gnutls_asn2err(result);
+       }
+
+       result =
+           asn1_write_value( dinfo, "digest", digest->data, digest->size);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               asn1_delete_structure(&dinfo);
+               return _gnutls_asn2err(result);
+       }
+
+       info->size = 128;
+       info->data = gnutls_malloc( info->size);
+       if (info->data == NULL) {
+               gnutls_assert();
+               asn1_delete_structure(&dinfo);
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       result = asn1_der_coding( dinfo, "", info->data, &info->size, NULL);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               asn1_delete_structure(&dinfo);
+               return _gnutls_asn2err(result);
+       }
+
+       asn1_delete_structure(&dinfo);
+               
+       return 0;
+}
+
+/* if hash==MD5 then we do RSA-MD5
+ * if hash==SHA then we do RSA-SHA
+ * params[0] is modulus
+ * params[1] is public key
+ */
+static int
+_pkcs1_rsa_sign( gnutls_mac_algorithm hash, const gnutls_datum* text,  
+       GNUTLS_MPI *params, int params_len, gnutls_datum* signature)
+{
+       int ret;
+       opaque _digest[MAX_HASH_SIZE];
+       GNUTLS_HASH_HANDLE hd;
+       gnutls_datum digest, info;
+
+       hd = _gnutls_hash_init( hash);
+       if (hd == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_HASH_FAILED;
+       }
+       
+       _gnutls_hash( hd, text->data, text->size);
+       _gnutls_hash_deinit( hd, _digest);
+
+       digest.data = _digest;
+       digest.size = _gnutls_hash_get_algo_len(hash);
+
+       /* Encode the digest as a DigestInfo
+        */
+       if ( (ret = encode_ber_digest_info( hash, &digest, &info)) != 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       if ( (ret=_gnutls_sign( GNUTLS_PK_RSA, params, params_len, &info, signature)) < 0) {
+               gnutls_assert();
+               _gnutls_free_datum( &info);
+               return ret;
+       }
+
+       _gnutls_free_datum( &info);
+
+       return 0;               
+}
+
+/* Signs the given data using the parameters from the signer's
+ * private key.
+ *
+ * returns 0 on success.
+ * 
+ * 'tbs' is the data to be signed
+ * 'signature' will hold the signature!
+ * 'hash' is only used in PKCS1 RSA signing.
+ */
+int _gnutls_x509_sign( const gnutls_datum* tbs, gnutls_mac_algorithm hash,
+       gnutls_x509_privkey signer, gnutls_datum* signature) 
+{
+int ret;
+
+       switch( signer->pk_algorithm)
+       {
+               case GNUTLS_PK_RSA:
+
+                       ret = _pkcs1_rsa_sign( hash, tbs, signer->params, signer->params_size,
+                               signature);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+                       return 0;
+                       break;
+
+               case GNUTLS_PK_DSA:
+                       ret = _gnutls_dsa_sign( signature, tbs, signer->params, signer->params_size);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+
+                       return 0;
+                       break;
+               default:
+                       gnutls_assert();
+                       return GNUTLS_E_INTERNAL_ERROR;
+       }
+
+}
+
diff --git a/lib/x509/sign.h b/lib/x509/sign.h
new file mode 100644 (file)
index 0000000..6c5df85
--- /dev/null
@@ -0,0 +1,2 @@
+int _gnutls_x509_sign( const gnutls_datum* tbs, gnutls_mac_algorithm hash,
+       gnutls_x509_privkey signer, gnutls_datum* signature);
index 536025abdc85a40c892c66932cc7873f6b2adc04..b2f348b668a48c0c25ca026662efd85cb6211157 100644 (file)
@@ -357,15 +357,11 @@ unsigned int _gnutls_x509_verify_certificate(gnutls_x509_crt * certificate_list,
 }
 
 
-#define OID_SHA1 "1.3.14.3.2.26"
-#define OID_MD5 "1.2.840.113549.2.5"
-#define OID_MD2 "1.2.840.113549.2.2"
-
 /* Reads the digest information.
  * we use DER here, although we should use BER. It works fine
  * anyway.
  */
-static int _gnutls_get_ber_digest_info( const gnutls_datum *info, gnutls_mac_algorithm *hash, 
+static int decode_ber_digest_info( const gnutls_datum *info, gnutls_mac_algorithm *hash, 
        opaque* digest, int *digest_size) 
 {
 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
@@ -442,7 +438,7 @@ _pkcs1_rsa_verify_sig( const gnutls_datum* text, const gnutls_datum* signature,
        int digest_size; 
        GNUTLS_HASH_HANDLE hd;
        gnutls_datum decrypted;
-       
+
        if ( (ret=_gnutls_pkcs1_rsa_decrypt( &decrypted, *signature, params, params_len, 1)) < 0) {
                gnutls_assert();
                return ret;
@@ -452,7 +448,7 @@ _pkcs1_rsa_verify_sig( const gnutls_datum* text, const gnutls_datum* signature,
         */
 
        digest_size = sizeof(digest);   
-       if ( (ret = _gnutls_get_ber_digest_info( &decrypted, &hash, digest, &digest_size)) != 0) {
+       if ( (ret = decode_ber_digest_info( &decrypted, &hash, digest, &digest_size)) != 0) {
                gnutls_assert();
                _gnutls_free_datum( &decrypted);
                return ret;
@@ -466,6 +462,11 @@ _pkcs1_rsa_verify_sig( const gnutls_datum* text, const gnutls_datum* signature,
        }
 
        hd = _gnutls_hash_init( hash);
+       if (hd == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_HASH_FAILED;
+       }
+
        _gnutls_hash( hd, text->data, text->size);
        _gnutls_hash_deinit( hd, md);
 
index 4c71a4cc687319f3f7ddf05dd1560f7a3a025736..f65ed0faa409be80037b10c7ab9d89e23195ccae 100644 (file)
@@ -19,6 +19,9 @@
  *
  */
 
+/* Functions on X.509 Certificate parsing
+ */
+
 #include <gnutls_int.h>
 #include <gnutls_datum.h>
 #include <gnutls_global.h>
@@ -46,7 +49,13 @@ int gnutls_x509_crt_init(gnutls_x509_crt * cert)
        *cert = gnutls_calloc( 1, sizeof(gnutls_x509_crt_int));
 
        if (*cert) {
-               (*cert)->cert = ASN1_TYPE_EMPTY;
+               int result = asn1_create_element(_gnutls_get_pkix(),
+                                    "PKIX1.Certificate",
+                                    &(*cert)->cert);
+               if (result != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       return _gnutls_asn2err(result);
+               }
                return 0;               /* success */
        }
        return GNUTLS_E_MEMORY_ERROR;
@@ -79,7 +88,7 @@ void gnutls_x509_crt_deinit(gnutls_x509_crt cert)
   * to the native gnutls_x509_crt format. The output will be stored in 'cert'.
   *
   * If the Certificate is PEM encoded it should have a header of "X509 CERTIFICATE", or
-  * "CERTIFICATE" and must be a null terminated string.
+  * "CERTIFICATE".
   *
   * Returns 0 on success.
   *
@@ -118,16 +127,6 @@ int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
                need_free = 1;
        }
 
-       cert->cert = ASN1_TYPE_EMPTY;
-
-       result = asn1_create_element(_gnutls_get_pkix(),
-                                    "PKIX1.Certificate",
-                                    &cert->cert);
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               return _gnutls_asn2err(result);
-       }
-
        result = asn1_der_decoding(&cert->cert, _data.data, _data.size, NULL);
        if (result != ASN1_SUCCESS) {
                result = _gnutls_asn2err(result);
@@ -205,8 +204,6 @@ int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
        return 0;
 
       cleanup:
-       if (cert->cert)
-               asn1_delete_structure(&cert->cert);
        _gnutls_free_datum(&cert->signed_data);
        _gnutls_free_datum(&cert->signature);
        if (need_free) _gnutls_free_datum( &_data);
@@ -1003,3 +1000,76 @@ gnutls_datum tmp;
 
        return gnutls_fingerprint( algo, &tmp, buf, sizeof_buf);
 }
+
+
+/* A generic export function. Will export the given ASN.1 encoded data
+ * to PEM or DER raw data.
+ */
+int _gnutls_x509_export_int( ASN1_TYPE asn1_data,
+       gnutls_x509_crt_fmt format, char* pem_header,
+       int tmp_buf_size, unsigned char* output_data, int* output_data_size)
+{
+       int result;
+       
+       if (format == GNUTLS_X509_FMT_DER) {
+               if ((result=asn1_der_coding( asn1_data, "", output_data, output_data_size, NULL)) != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       
+                       if (result == ASN1_MEM_ERROR)
+                               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+
+                       return _gnutls_asn2err(result);
+               }
+
+       } else { /* PEM */
+               opaque *tmp;
+               opaque *out;
+               int len;
+               
+               tmp = gnutls_alloca( tmp_buf_size);
+               if (tmp == NULL) {
+                       gnutls_assert();
+                       return GNUTLS_E_MEMORY_ERROR;
+               }
+               
+               len = tmp_buf_size - 1;
+               if ((result=asn1_der_coding( asn1_data, "", tmp, &len, NULL)) != ASN1_SUCCESS) {
+                       gnutls_assert();
+                       gnutls_afree(tmp);
+                       return _gnutls_asn2err(result);
+               }
+
+               result = _gnutls_fbase64_encode( pem_header,
+                                               tmp, len, &out);
+
+               gnutls_afree(tmp);
+
+               if (result < 0) {
+                       gnutls_assert();
+                       return result;
+               }
+
+               if (result == 0) {      /* oooops */
+                       gnutls_assert();
+                       return GNUTLS_E_INTERNAL_ERROR;
+               }
+
+               if (result + 1 > *output_data_size) {
+                       gnutls_assert();
+                       gnutls_free(out);
+                       *output_data_size = result;
+                       return GNUTLS_E_SHORT_MEMORY_BUFFER;
+               }
+
+               *output_data_size = result;
+               
+               if (output_data) {
+                       memcpy( output_data, out, result);
+                       output_data[result] = 0;
+               }
+               gnutls_free( out);
+               
+       }
+
+       return 0;
+}
index 4a2fc7818ff912fa355ff4b782d3f90a802cb399..4465e01a1a12e483cce416264343aeac93163430 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef X509_H
 # define X509_H
 
+#define OID_SHA1 "1.3.14.3.2.26"
+#define OID_MD5 "1.2.840.113549.2.5"
+#define OID_MD2 "1.2.840.113549.2.2"
+
 typedef struct gnutls_x509_crl_int {
        ASN1_TYPE crl;
        gnutls_datum signed_data; /* Holds the signed data of the CRL.
@@ -126,5 +130,8 @@ int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey key,
        gnutls_datum *d, gnutls_datum *p, gnutls_datum* q, 
        gnutls_datum* u);
 
+int _gnutls_x509_export_int( ASN1_TYPE asn1_data,
+       gnutls_x509_crt_fmt format, char* pem_header,
+       int tmp_buf_size, unsigned char* output_data, int* output_data_size);
 
 #endif