I was able to export a PKCS #8 encrypted key with either
SEC_OID_DES_EDE3_CBC or
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
which OpenSSL reads, I did not try other algorithms at the.
A somewhat sanitized extract of the pertinent function follows:
------------------------------------------------------------------------------------------------------------------------------------
/*
 * These code snippets illustrate how to export a private key to a
file
 */
#define ERROR_BREAK rv = SECFailure;break;
#define GEN_BREAK(e) rv=e; break;

/* Output the private key to a file.
 *  This function will write a key to a file encrypted according to
the algorithm specified in algTag.
 * @param keyoutfile the file to write the key to
 * @param key_pwd_file the file containing the key encryption
password, if NULL the key will not be encrypted.
 * @param privkey the private key to serialize to a file
 * @param pubkey the cooresponding public key
 * @param algTag the algorithm tag (SEC_OID_DES_EDE3_CBC and
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC are best)
 * @param accessPassword security module access password
 */
static SECStatus
KeyOut(const char *keyoutfile,
       const char *key_pwd_file,
       SECKEYPrivateKey *privkey,
       SECKEYPublicKey *pubkey,
       SECOidTag algTag,
       secuPWData *accessPassword,
       PRBool ascii)
{
    PRFileDesc *keyOutFile = NULL;
    PRUint32 total = 0;
    PRUint32 numBytes = 0;
    SECItem *derEPKI = NULL;
    SECItem derPKI = { 0, NULL, 0 };
    SECItem pwitem = { 0, NULL, 0 };
    PRArenaPool *arenaForEPKI = NULL;
    SECKEYEncryptedPrivateKeyInfo *epki = NULL;
    int rv = SECSuccess;

    do {
        if (!key_pwd_file) {
            /* Caller wants clear keys. Sorry, we don't support it. */
            GEN_BREAK(SECFailure);
        }
        /* Get the password from the file */
        if (!GetKeyPassword(key_pwd_file, &pwitem)) return 255;

        keyOutFile = PR_Open(keyoutfile, PR_RDWR | PR_CREATE_FILE |
PR_TRUNCATE, 00660);
        if (!keyOutFile) {
            PR_fprintf(PR_STDERR, "%s -o: unable to open \"%s\" for
writing\n", progName, keyoutfile);
            GEN_BREAK(255);
        }

        epki = PK11_ExportEncryptedPrivKeyInfo(NULL, algTag, &pwitem,
privkey, 1000, accessPassword);
        if (!epki) {
            rv = PORT_GetError();
            SECU_PrintError(progName, "Can't export private key info
(%d)\n", rv);
            GEN_BREAK(rv);
        }

        arenaForEPKI = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        assert(arenaForEPKI);

        /* NULL dest to let it allocate memory for us */
        derEPKI = SEC_ASN1EncodeItem(arenaForEPKI, NULL, epki,
SECKEY_EncryptedPrivateKeyInfoTemplate);
        if (rv != SECSuccess) {
            PR_fprintf(PR_STDERR, "%s ASN1 Encode failed (%dl)\n",
progName, rv);
            GEN_BREAK(rv);
        }

        if (ascii) {
            /* A PEM file is desired */
            SECItem *src  = derEPKI;
            char *header  = ENCRYPTED_KEY_HEADER;
            char *trailer = ENCRYPTED_KEY_TRAILER;
            char *b64 = NULL;
            do {
                b64 = BTOA_ConvertItemToAscii(src);
                assert(b64);
                total = PL_strlen(b64);
                PR_fprintf(keyOutFile, "%s\n", header);

                numBytes = PR_Write(keyOutFile, b64, total);
                if (numBytes != total) {
                    printf("Wrote  %d bytes, instead of %d\n",
numBytes, total);
                    break;
                }
                PR_fprintf(keyOutFile, "\n%s\n", trailer);
            } while (0);

            if (b64) PORT_Free(b64);

        } else {
            /* Write out the encrypted key in binary (DER encoded) */
            numBytes = PR_Write(keyOutFile, derEPKI, derEPKI->len);
        }

        /*printf("Wrote %d bytes of encoded data to %s \n", numBytes,
keyoutfile);*/

    } while (0);

    if (keyOutFile) PR_Close(keyOutFile);
    if (derEPKI != NULL) PORT_Free(derEPKI);
    if (arenaForEPKI) PORT_FreeArena(arenaForEPKI, PR_FALSE);

    return rv;
}
------------------------------------------------------------------------------------------------------------------------------------
Hope this helps some.

Elio


On Sep 30, 10:18 am, Robert Relyea <[EMAIL PROTECTED]> wrote:
> Subrata Mazumdar wrote:
> > Bob,
> > I implemented the importing and exporting of private key from PKCS#8
> > file using NSS API.
> > Here is what I found based on my testing :
>
> > Using Mozilla NSS API, I can only import/export private key in PKCS#8
> > format with
> > "PKCS12 V2 PBE With SHA1 And 3KEY Triple DES-cbc" encryption algorithm.
> > I would like to support other encryption algorithms supported by OpenSSL.
>
> Are you using NSS 3.11 or 3.12. We added PKCS 5 v2 (needed for the other
> algorithms in 3.12).
> I'm pretty sure Elio got support for other keys working.> Using NSS-API, I 
> can  import private key from OpenSSL generated PEM file
> > (openssl rsa ...) with
> > DES-EDE3-CBC (-des3 option) encryption only.
> > But, I cannot read the private key from Mozilla NSS API generated PEM
> > file using the OpenSSL API
> > because NSS uses 16 byte salt for encryption but the OpenSSL API expects
> > 8 byte salt.
>
> Hmm, sounds like a bug in openSSL, though I do remember tripping over
> this. I believe there is an NSS interface that lets you set the salt
> length specifically when generating the PBE (at least in NSS 3.12).
>
> bob
>
> > --
> > Subrata
>
> > Robert Relyea wrote:
>
> >> Subrata Mazumdar wrote:
>
> >>> Nelson,
> >>> thanks very much for the clear answer - I did not realize that the
> >>> Mozilla NSS does not support PKCS#8.
> >>> I also agree with you that PKCS#12 format is the right way to
> >>> import/export keys.
> >>> The problem is that a  large number of OpenSSL based applications
> >>> still use separate files
> >>> for private key and public key cert.  Actually, the problem is even
> >>> worse - some of the applications
> >>> use unencrypted private key or OpenSSL specific encrypted PEM file
> >>> (generated  using 'openssl rsa' command).
> >>> Any way, thanks once again.
>
> >> I believe Elio has some sample code that can import and export
> >> *wrapped* PKCS #8 keys stored in Pem format. Unwrapped keys are not
> >> considered safe. To support them you would need to manually
> >> encrypt/decrypt the wrapped keys. NSS does not have an interface to
> >> release unencrypted keys and applications are strongly discouraged
> >> from using them. Even openssl prefers encrypted to unencrypted keys.
>
> >> bob
>
> >>> --
> >>> Subrata
>
> >>> Nelson Bolyard wrote:
>
> >>>> Subrata Mazumdar wrote, On 2008-09-26 07:19:
>
> >>>>> Hi,
> >>>>> I am having problem in reading PKCS#8 file generated by OpenSSL
> >>>>> command line tool ("opnessl pkcs8").
>
> >>>> Officially, import and export of pkcs#8 files is not supported in NSS.
> >>>> You may or may not be able to get it to work, but because of the
> >>>> security concerns of PKCS#8 files, NSS does not support them.
>
> >>>> PKCS#12 is the supported way to import or export private keys and their
> >>>> related certificates. If you have a problem with PKCS#12, you can get
> >>>> support from the NSS team.
>
> >>>> PKCS#12 is the one universally implemented private key transport
> >>>> method.
> >>>> OpenSSL also supports PKCS#12, and so does Windows.
>
> >>> _______________________________________________
> >>> dev-tech-crypto mailing list
> >>> [EMAIL PROTECTED]
> >>>https://lists.mozilla.org/listinfo/dev-tech-crypto
>
> > _______________________________________________
> > dev-tech-crypto mailing list
> > [EMAIL PROTECTED]
> >https://lists.mozilla.org/listinfo/dev-tech-crypto
>
>
>
>  smime.p7s
> 4KViewDownload

_______________________________________________
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to