Wan-Teh Chang wrote:
> Dave,
>
> Thanks for the info.  So my time estimate is 100% off.  Sorry about that.
>
> The attribute type 3584088832 is CKA_NETSCAPE_DB (0xD5A0DB00L).
>
> In security/nss/lib/softoken/legacydb/lgattr.c, function
> lg_FindRSAPrivateKeyAttribute,
> could you try adding case CKA_NETSCAPE_DB like this:
>
> 836     case CKA_MODULUS:
> +       case CKA_NETSCAPE_DB:
> 837         return
> lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data,
> 838                                         key->u.rsa.modulus.len);

I tried this and though it made it past that attribute there are a few 
others giving the same problem. Their types are 355, 272 and 273. I also 
tried this with a shared db as Robert suggested and it appears to work 
correctly there in the test program I have.

> This could be a regression in NSS 3.12.  Do you know how to use
> NSS_3_11_9_RTM instead?

I'm having a little difficult trying this in 3.11, one of the functions 
I am using appears to be new in 3.12 (PK11_GetPBECryptoMechanism) so I'm 
not sure how I can backport this just yet.

Here is the test code I am using right now to import a key just in case 
there is anything obviously wrong with it:

SECStatus importKey(char *key, char *passphrase) {
     PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     // Decode it
     SECItem *rawdata;
     rawdata = NSSBase64_DecodeBuffer(arena, NULL, key, strlen(key));
     if (!rawdata) {
         PORT_FreeArena(arena, PR_FALSE);
         return SECFailure;
     }

     SECKEYEncryptedPrivateKeyInfo *epki;
     epki = (SECKEYEncryptedPrivateKeyInfo*)PORT_ArenaZAlloc(arena, 
sizeof(SECKEYEncryptedPrivateKeyInfo));
     if (!epki) {
         PORT_FreeArena(arena, PR_FALSE);
         return SECFailure;
     }

     SECStatus ss = SEC_ASN1Decode(arena, epki, 
SECKEY_EncryptedPrivateKeyInfoTemplate,
                                   reinterpret_cast<const 
char*>(rawdata->data), rawdata->len);
     if (ss != SECSuccess) {
         PORT_FreeArena(arena, PR_FALSE);
         return ss;
     }

     SECItem pwitem;
     pwitem.type = siAsciiString;
     pwitem.data = reinterpret_cast<unsigned char*>(passphrase);
     pwitem.len = strlen(passphrase);

     // Decrypt the key into derPKI
     SECItem *cryptoParam;
     CK_MECHANISM_TYPE cryptoMechType;
     cryptoMechType = PK11_GetPBECryptoMechanism(&epki->algorithm, 
&cryptoParam, &pwitem);
     if (cryptoMechType == CKM_INVALID_MECHANISM)  {
         PORT_FreeArena(arena, PR_FALSE);
         return SECFailure;
     }

     CK_MECHANISM cryptoMech;
     cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMechType);
     cryptoMech.pParameter = cryptoParam ? cryptoParam->data : NULL;
     cryptoMech.ulParameterLen = cryptoParam ? cryptoParam->len : 0;

     PK11SlotInfo *slot = PK11_GetInternalKeySlot();
     if (!slot) {
         SECITEM_FreeItem(cryptoParam, PR_TRUE);
         PORT_FreeArena(arena, PR_FALSE);
         return SECFailure;
     }

     PK11SymKey *symKey;
     symKey = PK11_PBEKeyGen(slot, &epki->algorithm, &pwitem, PR_FALSE, 
NULL);
     if (symKey == NULL) {
         SECITEM_FreeItem(cryptoParam, PR_TRUE);
         PK11_FreeSlot(slot);
         PORT_FreeArena(arena, PR_FALSE);
         return SECFailure;
     }

     PK11Context *ctx;
     ctx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, 
symKey, cryptoParam);
     if (ctx == NULL) {
         SECITEM_FreeItem(cryptoParam, PR_TRUE);
         PK11_FreeSlot(slot);
         PK11_FreeSymKey(symKey);
         PORT_FreeArena(arena, PR_FALSE);
         return SECFailure;
     }

     SECItem *derPKI;
     derPKI = SECITEM_AllocItem(arena, NULL, epki->encryptedData.len);

     ss = PK11_CipherOp(ctx, derPKI->data, 
reinterpret_cast<int*>(&derPKI->len),
                        (int)epki->encryptedData.len,
                        epki->encryptedData.data,
                        (int)epki->encryptedData.len);
     PK11_Finalize(ctx);
     PK11_FreeSymKey(symKey);
     SECITEM_FreeItem(cryptoParam, PR_TRUE);
     PK11_DestroyContext(ctx, PR_TRUE);

     if (ss != SECSuccess) {
         PK11_FreeSlot(slot);
         PORT_FreeArena(arena, PR_FALSE);
         return ss;
     }

     SECKEYPrivateKey *privKey;
     ss = PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI, NULL, NULL,
                                                   PR_TRUE, PR_FALSE, 0,
                                                   &privKey, NULL);
     PORT_FreeArena(arena, PR_FALSE);
     if (ss == SECSuccess)
         SECKEY_DestroyPrivateKey(privKey);
     PK11_FreeSlot(slot);
     return ss;
}
_______________________________________________
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to