]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
some pkcs12 improvements.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 23 Jun 2003 06:52:34 +0000 (06:52 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 23 Jun 2003 06:52:34 +0000 (06:52 +0000)
lib/gnutls_errors.c
lib/x509/common.h
lib/x509/pkcs12.c
lib/x509/pkcs12.h
lib/x509/pkcs12_bag.c
lib/x509/privkey_pkcs8.c

index 43d8a4c988c0ff8e0b08c0fff4fd3f2a2298a883..e8c9101204db4a654dbb3945c23b275c76ae9a1a 100644 (file)
@@ -43,6 +43,7 @@ static gnutls_error_entry error_algorithms[] = {
        /* "Short Description", Error code define, critical (0,1) -- 1 in most cases */
        ERROR_ENTRY("Success.", GNUTLS_E_SUCCESS, 0 ), 
        ERROR_ENTRY("Could not negotiate a supported cipher suite.", GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1 ), 
+       ERROR_ENTRY("The cipher type is unknown.", GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1 ), 
        ERROR_ENTRY("The certificate and the given key do not match.", GNUTLS_E_CERTIFICATE_KEY_MISMATCH, 1 ), 
        ERROR_ENTRY("Could not negotiate a supported compression method.", GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1 ), 
        ERROR_ENTRY("An unknown public key algorithm was encountered.", GNUTLS_E_UNKNOWN_PK_ALGORITHM, 1 ), 
index f40480d3778c20f318a2cc09162db8235c4cc10c..4564cd61c06d1e6eef9e60df4a7e85fafd5783c8 100644 (file)
@@ -49,5 +49,3 @@ int _gnutls_x509_export_int( ASN1_TYPE asn1_data,
 
 int _gnutls_x509_read_value( ASN1_TYPE c, const char* root, gnutls_datum *ret, int str);
 
-int _gnutls_x509_decrypt_pkcs7_encrypted_data( const gnutls_datum* data,
-        const char* password, gnutls_datum* dec);
index e60df40dad5f047cdc58870afcd8beda334a32f1..dfe22206398319479688739d9868c310ddde8d8f 100644 (file)
@@ -234,11 +234,6 @@ int gnutls_pkcs12_export( gnutls_pkcs12 pkcs12,
                output_data, output_data_size);
 }
 
-#define BAG_PKCS8_KEY "1.2.840.113549.1.12.10.1.1"
-#define BAG_PKCS8_ENCRYPTED_KEY "1.2.840.113549.1.12.10.1.2"
-#define BAG_CERTIFICATE "1.2.840.113549.1.12.10.1.3"
-#define BAG_CRL "1.2.840.113549.1.12.10.1.4"
-
 static int _oid2bag( const char* oid)
 {
        if (strcmp(oid, BAG_PKCS8_KEY)==0) 
@@ -254,26 +249,18 @@ static int _oid2bag( const char* oid)
 
 }
 
-
-static
-int _parse_safe_contents( ASN1_TYPE sc, const char* sc_name, gnutls_pkcs12_bag bag) 
+/* Decodes the SafeContents, and puts the output in
+ * the given bag.
+ */
+int
+_pkcs12_decode_safe_contents( const gnutls_datum* content, gnutls_pkcs12_bag bag)
 {
 char oid[128];
 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
-gnutls_datum content = { NULL, 0 };
 int len, result;
 int bag_type;
 
-       /* Step 1. Extract the content.
-        */
-
-       result = _gnutls_x509_read_value(sc, sc_name, &content, 1);
-       if (result < 0) {
-               gnutls_assert();
-               goto cleanup;
-       }
-
-       /* Step 2. Extract the SEQUENCE.
+       /* Step 1. Extract the SEQUENCE.
         */
 
        if ((result=asn1_create_element
@@ -283,13 +270,12 @@ int bag_type;
                goto cleanup;   
        }
 
-       result = asn1_der_decoding(&c2, content.data, content.size, NULL);
+       result = asn1_der_decoding(&c2, content->data, content->size, NULL);
        if (result != ASN1_SUCCESS) {
                gnutls_assert();
                result = _gnutls_asn2err(result);
                goto cleanup;   
        }
-       _gnutls_free_datum(&content);
 
        len = sizeof(oid);
        result = asn1_read_value(c2, "?1.bagId", oid, &len);
@@ -310,7 +296,6 @@ int bag_type;
 
        /* Read the Bag Value
         */
-
        result = _gnutls_x509_read_value( c2, "?1.bagValue", &bag->data, 0);
        if (result < 0) {
                gnutls_assert();
@@ -325,6 +310,37 @@ int bag_type;
 
        cleanup:
                if (c2) asn1_delete_structure(&c2);
+               return result;
+
+}
+
+
+static
+int _parse_safe_contents( ASN1_TYPE sc, const char* sc_name, gnutls_pkcs12_bag bag) 
+{
+gnutls_datum content = { NULL, 0 };
+int result;
+
+       /* Step 1. Extract the content.
+        */
+
+       result = _gnutls_x509_read_value(sc, sc_name, &content, 1);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       result = _pkcs12_decode_safe_contents( &content, bag);
+       if (result < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       _gnutls_free_datum( &content);
+
+       return 0;
+       
+       cleanup:
                _gnutls_free_datum( &content);
                return result;
 }
index 272fbb46081d1865ba4513562f8d3eca68c4935c..c337fd1275b65f375bb165c5292e5658749f9250 100644 (file)
@@ -18,6 +18,11 @@ typedef struct gnutls_pkcs12_bag_int {
        gnutls_pkcs12_bag_type type;
 } gnutls_pkcs12_bag_int;
 
+#define BAG_PKCS8_KEY "1.2.840.113549.1.12.10.1.1"
+#define BAG_PKCS8_ENCRYPTED_KEY "1.2.840.113549.1.12.10.1.2"
+#define BAG_CERTIFICATE "1.2.840.113549.1.12.10.1.3"
+#define BAG_CRL "1.2.840.113549.1.12.10.1.4"
+
 typedef struct gnutls_pkcs12_int *gnutls_pkcs12;
 typedef struct gnutls_pkcs12_bag_int *gnutls_pkcs12_bag;
 
@@ -35,3 +40,7 @@ void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag bag);
 int 
 _pkcs12_string_to_key (int id, const char *salt, int salt_size, int iter, const char *pw,
                int req_keylen, unsigned char *keybuf);
+
+int _gnutls_x509_decrypt_pkcs7_encrypted_data( const gnutls_datum* data,
+        const char* password, gnutls_datum* dec);
+int _pkcs12_decode_safe_contents( const gnutls_datum* content, gnutls_pkcs12_bag bag);
index 2c3f397ac05d4cf99119924db76b293f0202d884..f2145c43d1677fcb0516b45cceb9eac6b329d119 100644 (file)
@@ -107,20 +107,31 @@ int gnutls_pkcs12_bag_decrypt(gnutls_pkcs12_bag bag, const char* pass)
 {
 int ret;
 gnutls_datum dec;
+ASN1_TYPE sc = ASN1_TYPE_EMPTY;
        
        ret = _gnutls_x509_decrypt_pkcs7_encrypted_data( 
                &bag->data, pass, &dec);
 
         if (ret < 0) {
-               gnutls_assert();
+               gnutls_assert();
                return ret;
         }
-        
-        /* decryption succeeded */
-        
+
+        /* decryption succeeded. Now decode the SafeContents
+         * stuff, and parse it.
+         */
+
         _gnutls_free_datum( &bag->data);
-        
-        bag->data = dec;
+
+       ret = _pkcs12_decode_safe_contents( &dec, bag);
+
+        _gnutls_free_datum( &dec);
+
+        if (ret < 0) {
+               gnutls_assert();
+               return ret;
+        }
+                       
 
        return 0;
 }
index 218bdba32c37e6611c91972d30139971e52c2a66..88763b6da58abfec7355c1c8dee4a7d951b99000 100644 (file)
@@ -43,7 +43,8 @@
 
 typedef enum schema_id {
        PBES2,                  /* the stuff in PKCS #5 */
-       PKCS12_3DES_SHA1 /* the fucking stuff in PKCS #12 */
+       PKCS12_3DES_SHA1, /* the fucking stuff in PKCS #12 */
+       PKCS12_ARCFOUR_SHA1
 } schema_id;
 
 #define PBES2_OID "1.2.840.113549.1.5.13"
@@ -51,7 +52,8 @@ typedef enum schema_id {
 #define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
 
 /* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */
-#define PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
+#define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
+#define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1"
 
 struct pbkdf2_params {
        opaque salt[32];
@@ -105,9 +107,12 @@ inline static int check_schema(const char *oid)
        if (strcmp(oid, PBES2_OID) == 0)
                return PBES2;
 
-       if (strcmp(oid, PBE_3DES_SHA1_OID) == 0)
+       if (strcmp(oid, PKCS12_PBE_3DES_SHA1_OID) == 0)
                return PKCS12_3DES_SHA1;
 
+       if (strcmp(oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0)
+               return PKCS12_ARCFOUR_SHA1;
+
        _gnutls_x509_log("PKCS encryption schema OID '%s' is unsupported.\n", oid);
 
        return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
@@ -472,6 +477,16 @@ int read_pkcs_schema_params(schema_id schema, const char* password,
                break;
 
        case PKCS12_3DES_SHA1:
+       case PKCS12_ARCFOUR_SHA1:
+
+               if ((schema) == PKCS12_3DES_SHA1) {
+                       enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
+                       enc_params->iv_size = 8;
+               } else {
+                       enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
+                       enc_params->iv_size = 0;
+               }
+
                if ((result =
                     asn1_create_element(_gnutls_get_pkix(),
                                         "PKIX1.pkcs-12-PbeParams",
@@ -499,10 +514,9 @@ int read_pkcs_schema_params(schema_id schema, const char* password,
                        goto error;
                }
 
-               enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
-               enc_params->iv_size = 8;
-               _pkcs12_string_to_key( 2/*IV*/, kdf_params->salt, kdf_params->salt_size,
-                       kdf_params->iter_count, password, 8, enc_params->iv);
+               if (enc_params->iv_size)
+                       _pkcs12_string_to_key( 2/*IV*/, kdf_params->salt, kdf_params->salt_size,
+                               kdf_params->iter_count, password, enc_params->iv_size, enc_params->iv);
 
                asn1_delete_structure(&pbes2_asn);
 
@@ -1520,8 +1534,6 @@ int _gnutls_x509_decrypt_pkcs7_encrypted_data(const gnutls_datum * data,
                goto error;
        }
 
-       /* we only support PBES2 
-        */
        if ((result = check_schema(enc_oid)) < 0) {
                gnutls_assert();
                goto error;