]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
added new function to obtain information on a PKCS #12 encrypted bag
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 5 Aug 2014 09:02:30 +0000 (11:02 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 5 Aug 2014 09:02:30 +0000 (11:02 +0200)
New function: gnutls_pkcs12_bag_enc_info()

lib/includes/gnutls/pkcs12.h
lib/libgnutls.map
lib/x509/pkcs12_bag.c
lib/x509/privkey_pkcs8.c
lib/x509/x509_int.h

index 8b024e502bb85a4884c9a77030a37784a2479de2..c348c20275bd836aa27e8786d51dc55eb8e8fb43 100644 (file)
@@ -62,6 +62,10 @@ int gnutls_pkcs12_bag_decrypt(gnutls_pkcs12_bag_t bag, const char *pass);
 int gnutls_pkcs12_bag_encrypt(gnutls_pkcs12_bag_t bag,
                              const char *pass, unsigned int flags);
 
+int
+gnutls_pkcs12_bag_enc_info(gnutls_pkcs12_bag_t bag, unsigned int *schema, unsigned int *cipher,
+       void *salt, unsigned int *salt_size, unsigned int *iter_count, char **oid);
+
 #define GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED 1
 int gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12,
                               const char *password,
index 1c5944392cc108f3e636bb21f9500448de0c6962..bc5837d0ac28119df76e42a40bc6f4c2d0c72a6a 100644 (file)
@@ -1017,6 +1017,7 @@ GNUTLS_3_1_0 {
        gnutls_pkcs_schema_get_name;
        gnutls_pkcs_schema_get_oid;
        gnutls_pkcs8_info;
+       gnutls_pkcs12_bag_enc_info;
 } GNUTLS_3_0_0;
 
 GNUTLS_FIPS140 {
index b77ea46cf4e99c8dcb509ac09518bbd9ec3330f0..6a0e27a0c8682e2e364e44a3182ae7628f2cfb4d 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2003-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Red Hat
  *
  * Author: Nikos Mavrogiannopoulos
  *
@@ -779,5 +780,77 @@ gnutls_pkcs12_bag_encrypt(gnutls_pkcs12_bag_t bag, const char *pass,
        bag->bag_elements = 1;
 
 
+       return 0;
+}
+
+/**
+ * gnutls_pkcs12_bag_enc_info:
+ * @bag: The bag
+ * @schema: indicate the schema as one of %gnutls_pkcs_encrypt_flags_t
+ * @cipher: the cipher used as %gnutls_cipher_algorithm_t
+ * @salt: PBKDF2 salt (if non-NULL then @salt_size initially holds its size)
+ * @salt_size: PBKDF2 salt size
+ * @iter_count: PBKDF2 iteration count
+ * @oid: if non-NULL it will contain an allocated null-terminated variable with the OID
+ *
+ * This function will provide information on the encryption algorithms used
+ * in an encrypted bag. If the structure algorithms
+ * are unknown the code %GNUTLS_E_UNKNOWN_CIPHER_TYPE will be returned,
+ * and only @oid, will be set. That is, @oid will be set on encrypted bags
+ * whether supported or not. It must be deinitialized using gnutls_free().
+ * The other variables are only set on supported structures.
+ *
+ * Returns: %GNUTLS_E_INVALID_REQUEST if the provided bag isn't encrypted,
+ *  %GNUTLS_E_UNKNOWN_CIPHER_TYPE if the structure's encryption isn't supported, or
+ *  another negative error code in case of a failure. Zero on success.
+ **/
+int
+gnutls_pkcs12_bag_enc_info(gnutls_pkcs12_bag_t bag, unsigned int *schema, unsigned int *cipher,
+       void *salt, unsigned int *salt_size, unsigned int *iter_count, char **oid)
+{
+       int ret;
+       struct pbkdf2_params kdf;
+       const struct pbes2_schema_st *p;
+
+       if (bag == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       ret =
+           _gnutls_pkcs7_data_enc_info(&bag->element[0].data, &p, &kdf, oid);
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       if (schema)
+               *schema = p->flag;
+
+       if (cipher)
+               *cipher = p->cipher;
+
+       if (iter_count)
+                *iter_count = kdf.iter_count;
+
+       if (salt) {
+               if (*salt_size >= (unsigned)kdf.salt_size) {
+                       memcpy(salt, kdf.salt, kdf.salt_size);
+               } else {
+                       *salt_size = kdf.salt_size;
+                       return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+               }
+       }
+
+       if (salt_size)
+               *salt_size = kdf.salt_size;
+
+
        return 0;
 }
index 7bb3a67511cf0f3e49ef463370c498deb0d43dc1..c4abe60d4ebfb39b3e1384eaa6968ed8a90eb786 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2003-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Red Hat
+ * Copyright (C) 2014 Nikos Mavrogiannopoulos
  *
  * Author: Nikos Mavrogiannopoulos
  *
@@ -640,12 +642,12 @@ gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
  *
  * This function will provide information on the algorithms used
  * in a particular PKCS #8 structure. If the structure algorithms
- * are unknown the return code will be %GNUTLS_E_UNKNOWN_CIPHER_TYPE,
+ * are unknown the code %GNUTLS_E_UNKNOWN_CIPHER_TYPE will be returned,
  * and only @oid, will be set. That is, @oid will be set on encrypted PKCS #8
- * structures whether supported or not. The other variables are only set
- * on supported structures.
+ * structures whether supported or not. It must be deinitialized using gnutls_free().
+ * The other variables are only set on supported structures.
  *
- * Returns: %GNUTLS_E_DECRYPTION_FAILED if the provided structure isn't encrypted,
+ * Returns: %GNUTLS_E_INVALID_REQUEST if the provided structure isn't encrypted,
  *  %GNUTLS_E_UNKNOWN_CIPHER_TYPE if the structure's encryption isn't supported, or
  *  another negative error code in case of a failure. Zero on success.
  **/
@@ -692,6 +694,8 @@ gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
        }
 
        ret = pkcs8_key_info(&_data, &p, &kdf, oid);
+       if (ret == GNUTLS_E_DECRYPTION_FAILED)
+               ret = GNUTLS_E_INVALID_REQUEST;
        if (ret < 0) {
                gnutls_assert();
                goto cleanup;
@@ -706,17 +710,21 @@ gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
        if (cipher)
                *cipher = p->cipher;
 
+       if (iter_count)
+               *iter_count = kdf.iter_count;
+
        if (salt) {
                if (*salt_size >= (unsigned)kdf.salt_size) {
                        memcpy(salt, kdf.salt, kdf.salt_size);
+               } else {
+                       *salt_size = kdf.salt_size;
+                       return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
                }
        }
 
        if (salt_size)
                *salt_size = kdf.salt_size;
 
-       if (iter_count)
-               *iter_count = kdf.iter_count;
 
        return 0;
 
@@ -2433,7 +2441,7 @@ _gnutls_pkcs7_decrypt_data(const gnutls_datum_t * data,
 
 int
 _gnutls_pkcs7_data_enc_info(const gnutls_datum_t * data, const struct pbes2_schema_st **p,
-       struct pbkdf2_params *kdf_params)
+       struct pbkdf2_params *kdf_params, char **oid)
 {
        int result, len;
        char enc_oid[MAX_OID_SIZE];
@@ -2472,6 +2480,10 @@ _gnutls_pkcs7_data_enc_info(const gnutls_datum_t * data, const struct pbes2_sche
                goto error;
        }
 
+       if (oid) {
+               *oid = gnutls_strdup(enc_oid);
+       }
+
        if ((result = check_pkcs12_schema(enc_oid)) < 0) {
                gnutls_assert();
                goto error;
index 14277e7f662aa341979a169459ae6662be10f2af..69f1348e58eaa9b7b98e2148a15f377e58b496ba 100644 (file)
@@ -369,9 +369,10 @@ int _gnutls_pkcs_flags_to_schema(unsigned int flags);
 int _gnutls_pkcs7_encrypt_data(schema_id schema,
                               const gnutls_datum_t * data,
                               const char *password, gnutls_datum_t * enc);
+
 int
 _gnutls_pkcs7_data_enc_info(const gnutls_datum_t * data, const struct pbes2_schema_st **p,
-       struct pbkdf2_params *kdf_params);
+       struct pbkdf2_params *kdf_params, char **oid);
 
 int _pkcs12_decode_safe_contents(const gnutls_datum_t * content,
                                 gnutls_pkcs12_bag_t bag);