Bug 1399867, pk12util: Make -C try different password encoding if failed, r=rrelyea
authorDaiki Ueno <dueno@redhat.com>
Thu, 14 Sep 2017 15:14:45 +0200
changeset 13602 16eb0e48e4381bd8aa4128d75006d22215f6006f
parent 13601 3c7359ad3ce609ca7c4189c05cc05cf0fdac0db3
child 13603 e84403331d99bb1fcad4a879f42749332861e8e1
push id2383
push userkaie@kuix.de
push dateWed, 20 Sep 2017 10:06:29 +0000
reviewersrrelyea
bugs1399867
Bug 1399867, pk12util: Make -C try different password encoding if failed, r=rrelyea
cmd/pk12util/pk12util.c
--- a/cmd/pk12util/pk12util.c
+++ b/cmd/pk12util/pk12util.c
@@ -353,16 +353,17 @@ p12U_ReadPKCS12File(SECItem *uniPwp, cha
                     secuPWData *slotPw, secuPWData *p12FilePw)
 {
     SEC_PKCS12DecoderContext *p12dcx = NULL;
     p12uContext *p12cxt = NULL;
     SECItem *pwitem = NULL;
     SECItem p12file = { 0 };
     SECStatus rv = SECFailure;
     PRBool swapUnicode = PR_FALSE;
+    PRBool forceUnicode = pk12uForceUnicode;
     PRBool trypw;
     int error;
 
 #ifdef IS_LITTLE_ENDIAN
     swapUnicode = PR_TRUE;
 #endif
 
     p12cxt = p12u_InitContext(PR_TRUE, in_file);
@@ -420,23 +421,44 @@ p12U_ReadPKCS12File(SECItem *uniPwp, cha
         rv = SEC_PKCS12DecoderVerify(p12dcx);
         if (rv != SECSuccess) {
             if (uniPwp->len == 2) {
                 /* this is a null PW, try once more with a zero-length PW
                    instead of a null string */
                 SEC_PKCS12DecoderFinish(p12dcx);
                 uniPwp->len = 0;
                 trypw = PR_TRUE;
+            } else if (forceUnicode == pk12uForceUnicode) {
+                /* try again with a different password encoding */
+                forceUnicode = !pk12uForceUnicode;
+                rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE,
+                                   forceUnicode);
+                if (rv != SECSuccess) {
+                    SECU_PrintError(progName, "PKCS12 decoding failed to set option");
+                    pk12uErrno = PK12UERR_DECODEVERIFY;
+                    break;
+                }
+                SEC_PKCS12DecoderFinish(p12dcx);
+                trypw = PR_TRUE;
             } else {
                 SECU_PrintError(progName, "PKCS12 decode not verified");
                 pk12uErrno = PK12UERR_DECODEVERIFY;
                 break;
             }
         }
     } while (trypw == PR_TRUE);
+
+    /* revert the option setting */
+    if (forceUnicode != pk12uForceUnicode) {
+        rv = NSS_OptionSet(__NSS_PKCS12_DECODE_FORCE_UNICODE, pk12uForceUnicode);
+        if (rv != SECSuccess) {
+            SECU_PrintError(progName, "PKCS12 decoding failed to set option");
+            pk12uErrno = PK12UERR_DECODEVERIFY;
+        }
+    }
 /* rv has been set at this point */
 
 done:
     if (rv != SECSuccess) {
         if (p12dcx != NULL) {
             SEC_PKCS12DecoderFinish(p12dcx);
             p12dcx = NULL;
         }