Author: nnielsen
Date: Fri Feb 15 01:11:11 2008
New Revision: 1064
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1064&view=rev

Log:
        * common/gkr-crypto.c:
        * common/tests/unit-test-crypto.c:
        * pkix/gkr-pkix-der.c:
        * pkix/gkr-pkix-parser.c:
        * pkix/tests/test-data/unclient.p12: Try NULL passwords in addition to 
        empty passwords when parsing encrypted files. Fixes bug #514761


Added:
   trunk/pkix/tests/test-data/unclient.p12   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/common/gkr-crypto.c
   trunk/common/tests/unit-test-crypto.c
   trunk/pkix/gkr-pkix-der.c
   trunk/pkix/gkr-pkix-parser.c

Modified: trunk/common/gkr-crypto.c
==============================================================================
--- trunk/common/gkr-crypto.c   (original)
+++ trunk/common/gkr-crypto.c   Fri Feb 15 01:11:11 2008
@@ -383,15 +383,11 @@
                p += 64;
        }
        
-       /* Empty password is treated as a NULL password */
-       if(!utf8_password[0])
-               utf8_password = NULL;
-       
        /* Bring in the password, as 16bits per character BMP string, ie: UCS2 
*/
        if (utf8_password) {
                p2 = utf8_password;
                for (i = 0; i < 64; i += 2) {
-                       unich = g_utf8_get_char (p2);
+                       unich = *p2 ? g_utf8_get_char (p2) : 0;
                        *(p++) = (unich & 0xFF00) >> 8;
                        *(p++) = (unich & 0xFF);
                        if (*p2) /* Loop back to beginning if more bytes are 
needed */
@@ -468,13 +464,12 @@
        
        g_return_val_if_fail (cipher_algo, FALSE);
        g_return_val_if_fail (hash_algo, FALSE);
-       g_return_val_if_fail (password, FALSE);
        g_return_val_if_fail (iterations > 0, FALSE);
        
        n_key = gcry_cipher_get_algo_keylen (cipher_algo);
        n_block = gcry_cipher_get_algo_blklen (cipher_algo);
        
-       if (!g_utf8_validate (password, -1, NULL)) {
+       if (password && !g_utf8_validate (password, -1, NULL)) {
                g_warning ("invalid non-UTF8 password");
                g_return_val_if_reached (FALSE);
        }
@@ -601,7 +596,6 @@
        
        g_return_val_if_fail (hash_algo, FALSE);
        g_return_val_if_fail (cipher_algo, FALSE);
-       g_return_val_if_fail (password, FALSE);
        g_return_val_if_fail (iterations > 0, FALSE);
        
        n_key = gcry_cipher_get_algo_keylen (cipher_algo);

Modified: trunk/common/tests/unit-test-crypto.c
==============================================================================
--- trunk/common/tests/unit-test-crypto.c       (original)
+++ trunk/common/tests/unit-test-crypto.c       Fri Feb 15 01:11:11 2008
@@ -78,35 +78,52 @@
                "\xD6\xA6\xF0\x76\x66",
                NULL,
                NULL
-        },
-        
-        { /* 24 byte output */
-               "booo", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
-               "\xBD\xEE\x0B\xC6\xCF\x43\xAC\x25",
-               NULL,
-               
"\x3F\x38\x1B\x0E\x87\xEB\x19\xBE\xD1\x39\xDC\x5B\xC2\xD2\xB3\x3C\x35\xA8\xB8\xF9\xEE\x66\x48\x94",
-               
"\x20\x25\x90\xD8\xD6\x98\x3E\x71\x10\x17\x1F\x51\x49\x87\x27\xCA\x97\x27\xD1\xC9\x72\xF8\x11\xBB",
-               NULL
-        },
-
-        { /* Empty password, 24 byte output */
-               "", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
-               "\xF7\xCF\xD9\xCF\x1F\xF3\xAD\xF6",
-               NULL,
-               
"\x13\xce\xee\x4b\xaf\xca\x3e\xcd\xb6\x1d\x4c\x35\x3d\x16\xe5\x35\x76\xec\xf0\xf0\x9c\xa4\xf0\xd0"
-               
"\x53\xE3\x35\x9E\x5D\xC1\x85\x1A\x71\x3A\x67\x4E\x80\x56\x13\xD6\x4E\x3E\x89\x43\xB7\x1D\x5F\x7F",
-               NULL
-        },
+       },
+       
+       { /* Null Password, 5 byte output */
+               NULL, GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2000,
+               "\x04\xE0\x1C\x3E\xF8\xF2\xE9\xFD",
+               NULL,
+               "\x98\x7F\x20\x97\x1E",
+               NULL,
+               NULL
+       },
         
-        { /* 8 byte output */
-               "booo", GCRY_CIPHER_DES, GCRY_MD_MD5, 2048,
-               "\x93\x4C\x3D\x29\xA2\x42\xB0\xF5",
-               NULL, 
-               NULL,
-               NULL,
-               "\x8C\x67\x19\x7F\xB9\x23\xE2\x8D"
+       { /* 24 byte output */
+               "booo", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
+               "\xBD\xEE\x0B\xC6\xCF\x43\xAC\x25",
+               NULL,
+               
"\x3F\x38\x1B\x0E\x87\xEB\x19\xBE\xD1\x39\xDC\x5B\xC2\xD2\xB3\x3C\x35\xA8\xB8\xF9\xEE\x66\x48\x94",
+               
"\x20\x25\x90\xD8\xD6\x98\x3E\x71\x10\x17\x1F\x51\x49\x87\x27\xCA\x97\x27\xD1\xC9\x72\xF8\x11\xBB",
+               NULL
+       },
+
+       { /* Empty password, 24 byte output */
+               "", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
+               "\xF7\xCF\xD9\xCF\x1F\xF3\xAD\xF6",
+               NULL,
+               NULL,
+               
"\x53\xE3\x35\x9E\x5D\xC1\x85\x1A\x71\x3A\x67\x4E\x80\x56\x13\xD6\x4E\x3E\x89\x43\xB7\x1D\x5F\x7F",
+               NULL
+       },
 
-        }
+       { /* Empty password, 24 byte output */
+               "", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
+               "\xD9\xB3\x2E\xC7\xBA\x1A\x8E\x15",
+               NULL,
+               
"\x39\x70\x75\x7C\xF5\xE2\x13\x0B\x5D\xC2\x9D\x96\x8B\x71\xC7\xFC\x5B\x97\x1F\x79\x9F\x06\xFC\xA2",
+               NULL,
+               NULL
+       },
+       
+       { /* 8 byte output */
+               "booo", GCRY_CIPHER_DES, GCRY_MD_MD5, 2048,
+               "\x93\x4C\x3D\x29\xA2\x42\xB0\xF5",
+               NULL, 
+               NULL,
+               NULL,
+               "\x8C\x67\x19\x7F\xB9\x23\xE2\x8D"
+       }
 };
 
 #define N_GENERATION_TESTS (sizeof (all_generation_tests) / sizeof 
(all_generation_tests[0]))

Modified: trunk/pkix/gkr-pkix-der.c
==============================================================================
--- trunk/pkix/gkr-pkix-der.c   (original)
+++ trunk/pkix/gkr-pkix-der.c   Fri Feb 15 01:11:11 2008
@@ -962,7 +962,6 @@
        g_return_val_if_fail (oid_scheme != 0, GKR_PKIX_FAILURE);
        g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
        g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
-       g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
        
        init_quarks ();
        
@@ -1037,7 +1036,6 @@
        g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, 
GKR_PKIX_FAILURE);
        g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
        g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
-       g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
 
        *cih = NULL;    
        ret = GKR_PKIX_UNRECOGNIZED;
@@ -1167,7 +1165,6 @@
        gsize n_salt, n_key;
        guint iterations;
        
-       g_assert (password);
        g_assert (cipher_algo);
        g_assert (data);
        
@@ -1220,7 +1217,6 @@
 
        g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
        g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
-       g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
        
        init_quarks ();
        
@@ -1330,7 +1326,6 @@
        g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, 
GKR_PKIX_FAILURE);
        g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
        g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
-       g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
        
        *cih = NULL;
        ret = GKR_PKIX_UNRECOGNIZED;

Modified: trunk/pkix/gkr-pkix-parser.c
==============================================================================
--- trunk/pkix/gkr-pkix-parser.c        (original)
+++ trunk/pkix/gkr-pkix-parser.c        Fri Feb 15 01:11:11 2008
@@ -141,19 +141,20 @@
  * HELPERS
  */
  
-static const gchar*
+static gboolean
 enum_next_password (GkrPkixParser *parser, GQuark loc, gkrid digest, 
-                    GQuark type, const gchar *label, PasswordState *state)
+                    GQuark type, const gchar *label, PasswordState *state, 
+                    const gchar **password)
 {
        GkrPkixParserPrivate *pv = GKR_PKIX_PARSER_GET_PRIVATE (parser);
        gboolean first = FALSE;
        gchar *display = NULL;
-       gchar *password;
        guint passes;
+       gchar *prompted;
        GSList *l;
 
        if (gkr_async_is_stopping ())
-               return NULL;
+               return FALSE;
 
        /* Is it a new location, reset stuff */
        if (loc != state->location) {
@@ -167,19 +168,27 @@
        ++state->n_passes;
                
        /* 
-        * On the first pass always try an empty password. This helps with 
-        * two things.
+        * On the first pass always try a NULL and then an empty password. 
+        * This helps with two things.
         *  
         * 1. Often code will call this function, without actually parsing
         *    any data yet. So this prevents us prompting the user without
         *    knowing it will parse. 
         *  
         * 2. In case it is actually an empty password, we don't want to 
-        *    prompt the user, just 'decrypt' it.
+        *    prompt the user, just 'decrypt' it. Note that some systems
+        *    use the null password instead of empty, so we try both.
         */
-       if (passes == 0) 
-               return "";
-               
+       if (passes == 0) {
+               *password = "";
+               return TRUE;
+       }
+       
+       if (passes == 1) {
+               *password = NULL;
+               return TRUE;
+       }
+       
        /* 
         * Next passes we look through all the passwords that the parser 
         * has seen so far. This is because different parts of a encrypted
@@ -198,14 +207,18 @@
        l = state->seen;
        
        /* Return first seen password? */
-       if (first && l && l->data)
-               return (const gchar*)l->data;
+       if (first && l && l->data) {
+               *password = (const gchar*)l->data;
+               return TRUE;
+       }
        
        /* Return next seen password? */
        if (l && l->next) {
                l = state->seen = state->seen->next;
-               if (l->data)
-                       return (const gchar*)l->data;
+               if (l->data) {
+                       *password = (const gchar*)l->data;
+                       return TRUE;
+               }
        }
        
        /* 
@@ -217,15 +230,19 @@
                label = display = gkr_location_to_display (loc);
        
        g_signal_emit (parser, signals[ASK_PASSWORD], 0, 
-                      loc, digest, type, label, state->n_prompts, &password);
+                      loc, digest, type, label, state->n_prompts, &prompted);
                       
        ++state->n_prompts;
        g_free (display);
        
        /* Stash away any password */
-       if (password)
-               pv->seen_passwords = g_slist_prepend (pv->seen_passwords, 
password);    
-       return password;
+       if (prompted) {
+               pv->seen_passwords = g_slist_prepend (pv->seen_passwords, 
prompted);
+               *password = prompted;
+               return TRUE;
+       }
+       
+       return FALSE;
 }
 
 static void
@@ -670,14 +687,12 @@
                
                g_assert (cih == NULL);
                
-               password = enum_next_password (parser, location, digest, 
GKR_PKIX_PRIVATE_KEY, NULL, &pstate);
-
-               /* If no password is available, we still know it's a key, so 
'partial' parse */
-               if (!password) {
-                       fire_parsed_partial (parser, location, digest, 
GKR_PKIX_PRIVATE_KEY);
-                       ret = GKR_PKIX_SUCCESS;
-                       goto done; 
-               }
+       /* If no password is available, we still know it's a key, so 'partial' 
parse */
+        if (!enum_next_password (parser, location, digest, 
GKR_PKIX_PRIVATE_KEY, NULL, &pstate, &password)) {
+               fire_parsed_partial (parser, location, digest, 
GKR_PKIX_PRIVATE_KEY);
+               ret = GKR_PKIX_SUCCESS;
+               goto done; 
+        }
                
                /* 
                 * Parse the encryption stuff into a cipher. 
@@ -942,8 +957,7 @@
                
                g_assert (cih == NULL);
                
-               password = enum_next_password (parser, loc, digest, 0, NULL, 
&pstate);
-               if (!password) {
+               if (!enum_next_password (parser, loc, digest, 0, NULL, &pstate, 
&password)) {
                        fire_parsed_partial (parser, loc, digest, 0);
                        ret = GKR_PKIX_SUCCESS;
                        goto done; 
@@ -1339,13 +1353,11 @@
                
        while (!gkr_async_is_stopping ()) {
 
-               password = enum_next_password (parser, location, digest, 
parsed, NULL, &pstate);
-
-               /* If no password is available, we still know what it was, so 
'partial' parse */
-               if (!password) {
-                       fire_parsed_partial (parser, location, digest, parsed);
-                       return GKR_PKIX_SUCCESS;
-               }
+       /* If no password is available, we still know what it was, so 'partial' 
parse */
+               if (!enum_next_password (parser, location, digest, parsed, 
NULL, &pstate, &password)) {
+               fire_parsed_partial (parser, location, digest, parsed);
+               return GKR_PKIX_SUCCESS;
+        }
                
                decrypted = NULL;
                n_decrypted = 0;

Added: trunk/pkix/tests/test-data/unclient.p12
==============================================================================
Binary file. No diff available.
_______________________________________________
SVN-commits-list mailing list (read only)
http://mail.gnome.org/mailman/listinfo/svn-commits-list

Want to limit the commits to a few modules? Go to above URL, log in to edit 
your options and select the modules ('topics') you want.
Module maintainer? It is possible to set the reply-to to your development 
mailing list. Email [EMAIL PROTECTED] if interested.

Reply via email to