Make password callback work (PKCS8 support), fix minor bugs and add more tests.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 14 Nov 2008 17:34:51 +0000 (17:34 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 14 Nov 2008 17:34:51 +0000 (17:34 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eet@37625 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/Eet_private.h
src/lib/eet_cipher.c
src/lib/eet_lib.c
src/tests/eet_suite.c
src/tests/key_enc.pem [new file with mode: 0644]
src/tests/key_enc_none.pem [new file with mode: 0644]

index acbd981..e3a1435 100644 (file)
 # include <config.h>
 #endif
 
-#ifdef HAVE_GNUTLS
-# include <gnutls/gnutls.h>
-# include <gnutls/x509.h>
-#else
-#ifdef HAVE_OPENSSL
-# include <openssl/evp.h>
-# include <openssl/x509.h>
-# include <openssl/pem.h>
-#endif
-#endif
-
 typedef struct _Eet_String              Eet_String;
 
 struct _Eet_String
@@ -68,20 +57,6 @@ struct _Eet_Dictionary
   const char   *end;
 };
 
-struct _Eet_Key
-{
-   int          references;
-#ifdef HAVE_SIGNATURE
-# ifdef HAVE_GNUTLS
-   gnutls_x509_crt_t           certificate;
-   gnutls_x509_privkey_t       private_key;
-# else
-   X509               *certificate;
-   EVP_PKEY    *private_key;
-# endif
-#endif
-};
-
 Eet_Dictionary  *eet_dictionary_add(void);
 void             eet_dictionary_free(Eet_Dictionary *ed);
 int              eet_dictionary_string_add(Eet_Dictionary *ed, const char *string);
index ac6d216..2de8711 100644 (file)
@@ -16,6 +16,7 @@
 #ifdef HAVE_SIGNATURE
 # ifdef HAVE_GNUTLS
 #  include <gnutls/gnutls.h>
+#  include <gnutls/x509.h>
 # else
 #  include <openssl/rsa.h>
 #  include <openssl/objects.h>
@@ -23,6 +24,9 @@
 #  include <openssl/ssl.h>
 #  include <openssl/dh.h>
 #  include <openssl/dsa.h>
+#  include <openssl/evp.h>
+#  include <openssl/x509.h>
+#  include <openssl/pem.h>
 # endif
 #endif
 
@@ -61,6 +65,20 @@ static Eet_Error eet_hmac_sha1(const void *key, size_t key_len, const void *data
 static Eet_Error eet_pbkdf2_sha1(const char *key, int key_len, const unsigned char *salt, unsigned int salt_len, int iter, unsigned char *res, int res_len);
 #endif
 
+struct _Eet_Key
+{
+   int          references;
+#ifdef HAVE_SIGNATURE
+# ifdef HAVE_GNUTLS
+   gnutls_x509_crt_t           certificate;
+   gnutls_x509_privkey_t       private_key;
+# else
+   X509               *certificate;
+   EVP_PKEY    *private_key;
+# endif
+#endif
+};
+
 EAPI Eet_Key*
 eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb)
 {
@@ -75,6 +93,7 @@ eet_identity_open(const char *certificate_file, const char *private_key_file, Ee
   void *data = NULL;
   gnutls_datum_t load_file = { NULL, 0 };
   int res;
+  char pass[1024];
 
   /* Init */
   if (!(key = malloc(sizeof(Eet_Key)))) goto on_error;
@@ -111,8 +130,23 @@ eet_identity_open(const char *certificate_file, const char *private_key_file, Ee
   /* Import the private key in Eet_Key structure */
   load_file.data = data;
   load_file.size = st.st_size;
+  /* Try to directly import the PEM encoded private key */
   if ((res = gnutls_x509_privkey_import(key->private_key, &load_file, GNUTLS_X509_FMT_PEM)) < 0)
-    goto on_error;
+    {
+      /* Else ask for the private key pass */
+      if (cb && cb(pass, 1024, 0, NULL))
+       {
+         /* If pass then try to decode the pkcs 8 private key */
+         if ((res = gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file, GNUTLS_X509_FMT_PEM, pass, 0)))
+           goto on_error;
+       }
+      else
+       {
+         /* Else try to import the pkcs 8 private key without pass */
+         if ((res = gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file, GNUTLS_X509_FMT_PEM, NULL, 1)))
+           goto on_error;
+       }
+    }
   if (munmap(data, st.st_size)) goto on_error;
   fclose(fp);
 
@@ -230,14 +264,15 @@ eet_identity_print(Eet_Key *key, FILE *out)
            }
          if (err) goto on_error;
 
-         fprintf(out, "%s:\n", names[i]);
+         fprintf(out, "\t%s:\n", names[i]);
          for (j = 0; strlen(res) > j; j += 32)
            {
              snprintf(buf, 32, "%s", res + j);
-             fprintf(out, "\t%s\n", buf);
+             fprintf(out, "\t\t%s\n", buf);
            }
        }
       free(res);
+      res = NULL;
     }
 
   if (key->certificate)
@@ -246,7 +281,9 @@ eet_identity_print(Eet_Key *key, FILE *out)
       if (gnutls_x509_crt_print(key->certificate, GNUTLS_X509_CRT_FULL, &data)) goto on_error;
       fprintf(out, "%s", data.data);
       gnutls_free(data.data);
+      data.data = NULL;
     }
+
  on_error:
   if (res) free(res);
   if (data.data) gnutls_free(data.data);
index bcdbf2e..44b510c 100644 (file)
@@ -58,6 +58,7 @@ void *alloca (size_t);
 
 #ifdef HAVE_OPENSSL
 # include <openssl/err.h>
+# include <openssl/evp.h>
 #endif
 
 #include <Eina.h>
@@ -739,6 +740,7 @@ eet_init(void)
 #endif
 #ifdef HAVE_OPENSSL
    ERR_load_crypto_strings();
+   OpenSSL_add_all_algorithms();
 #endif
 
    eina_init();
@@ -758,6 +760,7 @@ eet_shutdown(void)
    gnutls_global_deinit();
 #endif
 #ifdef HAVE_OPENSSL
+   EVP_cleanup();
    ERR_free_strings();
 #endif
 
index 26ddd9e..48da983 100644 (file)
@@ -1275,6 +1275,88 @@ START_TEST(eet_identity_simple)
 }
 END_TEST
 
+START_TEST(eet_identity_open_simple)
+{
+   Eet_Key *k = NULL;
+
+   eet_init();
+
+   chdir("src/tests");
+
+   k = eet_identity_open("cert.pem", "key.pem", NULL);
+   fail_if(!k);
+
+   if (k) eet_identity_close(k);
+
+   eet_shutdown();
+}
+END_TEST
+
+START_TEST(eet_identity_open_pkcs8)
+{
+   Eet_Key *k = NULL;
+
+   eet_init();
+
+   chdir("src/tests");
+
+   k = eet_identity_open("cert.pem", "key_enc_none.pem", NULL);
+   fail_if(!k);
+
+   if (k) eet_identity_close(k);
+
+   eet_shutdown();
+}
+END_TEST
+
+static int pass_get(char *pass, int size, __UNUSED__ int rwflags, __UNUSED__ void *u)
+{
+   memset(pass, 0, size);
+
+   if (strlen("password") > size)
+     return 0;
+   snprintf(pass, size, "%s", "password");
+   return strlen(pass);
+}
+
+static int badpass_get(char *pass, int size, __UNUSED__ int rwflags, __UNUSED__ void *u)
+{
+   memset(pass, 0, size);
+
+   if (strlen("bad password") > size)
+     return 0;
+   snprintf(pass, size, "%s", "bad password");
+   return strlen(pass);
+}
+
+
+START_TEST(eet_identity_open_pkcs8_enc)
+{
+   Eet_Key *k = NULL;
+
+   eet_init();
+
+   chdir("src/tests");
+
+   k = eet_identity_open("cert.pem", "key_enc.pem", NULL);
+   fail_if(k);
+
+   if (k) eet_identity_close(k);
+
+   k = eet_identity_open("cert.pem", "key_enc.pem", &badpass_get);
+   fail_if(k);
+
+   if (k) eet_identity_close(k);
+
+   k = eet_identity_open("cert.pem", "key_enc.pem", &pass_get);
+   fail_if(!k);
+
+   if (k) eet_identity_close(k);
+
+   eet_shutdown();
+}
+END_TEST
+
 START_TEST(eet_cipher_decipher_simple)
 {
    const char *buffer = "Here is a string of data to save !";
@@ -1361,6 +1443,9 @@ eet_suite(void)
 #ifdef HAVE_SIGNATURE
    tc = tcase_create("Eet Identity");
    tcase_add_test(tc, eet_identity_simple);
+   tcase_add_test(tc, eet_identity_open_simple);
+   tcase_add_test(tc, eet_identity_open_pkcs8);
+   tcase_add_test(tc, eet_identity_open_pkcs8_enc);
    suite_add_tcase(s, tc);
 #endif
 
diff --git a/src/tests/key_enc.pem b/src/tests/key_enc.pem
new file mode 100644 (file)
index 0000000..83c1ba2
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQILLqDZE1i0Y8CAggA
+MBQGCCqGSIb3DQMHBAjwbnSdTCCDOASCAoB0rMuSIXrzqFQnCexMkC9A5jyd+HvC
+2UV6EWIfFU4yBvp+2dfHg6RKUoZ0wGk8FxAkaAj+boVwf16PPXXQ70AQBb0iGeb4
+YLdjDF2zSoIK3SbsWrhAfJhSMbcMftEZnLTYxLSkTv5R8jb0IPybVNTqFf+KmGav
+DwyRVQrdAxIYdJSPwd61Fhs1VqzptmQ8DLKHy35X1fIro3py4jncBhsuqf6H3yj1
+ZFuzCPnwB8unASgbTPD43yObrjyWTjbTtp59WavVdnNS+m7QNW+OfxznHUUJXtMz
+/EniglUhR1Uf75wpMpQIPfC77Cary0Y4iLGQZiF1C0WjQzMBufckJFJVRFGfkkMl
+ijlaijLUYMqENJ6wsyK5lihsoBCzIDoqI375s9pdeln8sd33Yu+L/Gu4Xo8Bh5cM
+6mlo9WUgw5KibmlZHGEAGdKxcvL0ywswuwQ6yhwcdvCAt6MfrWJNpksa9JmpXJi8
+c21lHwnoyG1DgSqY5VhRyitfnuY3Jegj+7njhooiAJM9w7fxpafN9oxiaJBvPFqd
+lfJ42Pj5rkjjVqXOJX7Cf7sF85tW7ygwdGWyXvHn2fhQ+vjaDtZalry//Xytet4r
+lvTerO6M6WVMk2yM7vdeBU7c74LVIJmwGR6d837OPax1V+Z9yq6zDuJAQ3l9mtmu
+gowV3xInTFRsnSOQcYW5y8dNnugR9FBh8f1NI7SPyW0reeVbPXXhRxg+TyogIXhh
+yAfWJ6dDLZ31EVCdqRKxK7b9u2r3dsuaiwT1jFg59Eu2AifFi0j7aDA1lGIKoj3C
+cPDwJd8weC+UoWpWX/O4KOpaU62Rwt5wRoOxELG6lHy7cOjZgLmwjg1G
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/src/tests/key_enc_none.pem b/src/tests/key_enc_none.pem
new file mode 100644 (file)
index 0000000..1163851
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMiE486eROKePG0/
+639D4XTTDR9XSRWp1xqZzq7P+jjWRFbZ/MWVIVzkc4MRm83UOolbPj76LjM10cse
+aVAhK7G9CHp2dur4alWvdCXPH5Q+LPOFS9gMx0Jz9EZeHHOHZKLyJdKSmot+zluw
+JTLe081RRUwzNKct6JrVVG/7SmITAgMBAAECgYB8ssfI0nwcQjNp7XpSZrBqqmVa
+vDljE4AFtujlpckCV52gNWgQp7Fbx2ZeeDDgS78rdGa9W3AnwKx7GKp9fmNgxT5g
+pFvDDpWqv+m6chSGIQdVqscwUob3KjXipJrPbE+Be8Lmnv9GFyL6sBSnfpLmQgdy
+HmwuEQRwlrLKbLMPIQJBAP/kHcl2lyi+tIj6fJnwi5vb4jd/e6jHqbUMrEd5p3bo
+gKgivtUKc9XknWAsgHYyh9UJsqGbLg82LlrRB29rMl8CQQDImr1j71JDiwI5UOsW
+SUnGFe5kThZudHfZewF2dD11q6jQTa8NWS/qYefMxauhOMu/iEfme58Tk28yjw80
+YHTNAkAU4qR/vfsmazJG/9LNqbFrXi3/g5svMmSqj0c8ajR94wolLvjOYJUFvywN
+HnS5sPQfMjRvNkAzI6Py656kvGYXAkAf5FHluF94s3nYCOBG+8HJxyTON4fjaYrA
+PYj+/v3iXjcJXsBMu/gdKBGFAYwGppPl0FG198NThmXwQMQnDIqlAkEAnY01pxRF
+PJq9Tr31Ak4h0YCwDgpeJyLwfc+65Yy0ctFEp08V5oJGf72ntOCV/Ssf2FQY6lRc
+dgPf4QK3qCdUNw==
+-----END PRIVATE KEY-----