summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-06-23 06:52:34 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-06-23 06:52:34 +0000
commit65ee78490288377151bb6c9ea3e5fb53a46adce0 (patch)
tree25de3e3b04e6ddb2b97f5e66ccf43c010b62d7a9
parentb9d6179114200c574d572858dbe36a2b49bbc268 (diff)
downloadgnutls-65ee78490288377151bb6c9ea3e5fb53a46adce0.tar.gz
some pkcs12 improvements.
-rw-r--r--lib/gnutls_errors.c1
-rw-r--r--lib/x509/common.h2
-rw-r--r--lib/x509/pkcs12.c60
-rw-r--r--lib/x509/pkcs12.h9
-rw-r--r--lib/x509/pkcs12_bag.c23
-rw-r--r--lib/x509/privkey_pkcs8.c30
6 files changed, 86 insertions, 39 deletions
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 43d8a4c988..e8c9101204 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -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 ),
diff --git a/lib/x509/common.h b/lib/x509/common.h
index f40480d377..4564cd61c0 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -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);
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index e60df40dad..dfe2220639 100644
--- a/lib/x509/pkcs12.c
+++ b/lib/x509/pkcs12.c
@@ -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;
}
diff --git a/lib/x509/pkcs12.h b/lib/x509/pkcs12.h
index 272fbb4608..c337fd1275 100644
--- a/lib/x509/pkcs12.h
+++ b/lib/x509/pkcs12.h
@@ -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);
diff --git a/lib/x509/pkcs12_bag.c b/lib/x509/pkcs12_bag.c
index 2c3f397ac0..f2145c43d1 100644
--- a/lib/x509/pkcs12_bag.c
+++ b/lib/x509/pkcs12_bag.c
@@ -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;
}
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index 218bdba32c..88763b6da5 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -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;