简体   繁体   中英

OpenSSL debugging - how to dump intermediate ASN.1 inside openssl?

I have a PKCS#12 test file with a single entry encrypted with PBES2 (PBEWithHmacSHA256AndAES_256) that is not working inside OpenSSL (but works elsewhere).

So I'm trying to figure out if my file is broken or if OpenSSL is unable to handle PBES2 properly.

The file is attached: test.p12 ( pass:test )

The output from openssl pkcs12 (v.1.0.2p-dev) is:

$ openssl pkcs12 -info -nodes -in out.p12 -passin pass:test
MAC Iteration 100000
MAC verified OK
PKCS7 Data
Shrouded Keybag: PBES2<unsupported parameters>
Bag Attributes
    friendlyName: test
    localKeyID: 54 69 6D 65 20 31 35 33 30 38 32 31 38 34 39 32 39 39
Error outputting keys and certificates
10564:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:.\crypto\asn1\tasn_dec.c:1220:
10564:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:386:Type=X509_ALGOR
10564:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:720:Field=keyfunc, Type=PBE2PARAM

I've traced it to these lines in pkcs12.c :

if (pbenid == NID_pbes2) {
    PBE2PARAM *pbe2 = NULL;
    int encnid;
    if (aparamtype == V_ASN1_SEQUENCE)
        pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM)); // <=== fails here
    if (pbe2 == NULL) {
        BIO_puts(x, "<unsupported parameters>");
        goto done;
    }

Hence my main question: what's the best way to debug this further?

I've been thinking about two approaches:

  1. Inspect the ASN.1 fragment while inside ASN1_item_unpack() (how?)
  2. Get the decrypted PKCS#12 stream and run asn1parse on it (how?)

TLDR: your file is broken.

You can't decrypt that portion of the file because of the error, but you don't need to because the encryption parameters are unencrypted, precisely because the decrypter needs to parse them before it can decrypt, and we can mimic that with commandline asn1parse . First parse the outer structure:

$ openssl asn1parse -in test.p12 -inform der -i 
    0:d=0  hl=4 l=2450 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim:  INTEGER           :03
    7:d=1  hl=4 l=2379 cons:  SEQUENCE
   11:d=2  hl=2 l=   9 prim:   OBJECT            :pkcs7-data
   22:d=2  hl=4 l=2364 cons:   cont [ 0 ]
   26:d=3  hl=4 l=2360 prim:    OCTET STRING      [HEX DUMP]:308209343[REDACTED]
 2390:d=1  hl=2 l=  62 cons:  SEQUENCE
 2392:d=2  hl=2 l=  33 cons:   SEQUENCE
 2394:d=3  hl=2 l=   9 cons:    SEQUENCE
 2396:d=4  hl=2 l=   5 prim:     OBJECT            :sha1
 2403:d=4  hl=2 l=   0 prim:     NULL
 2405:d=3  hl=2 l=  20 prim:    OCTET STRING      [HEX DUMP]:17774B593A099F0332A817D2510FE15A0C699159
 2427:d=2  hl=2 l=  20 prim:   OCTET STRING      [HEX DUMP]:814F2DB1C2EBCB64D38CD56881BC9AC2FD2936FB
 2449:d=2  hl=2 l=   3 prim:   INTEGER           :0186A0

which correctly matches PFX from rfc2898 section 4 . All of the useful content is in the contentinfo, at 26+4=30, so parse that:

$ openssl asn1parse -in test.p12 -inform der -i -strparse 30
    0:d=0  hl=4 l=2356 cons: SEQUENCE
    4:d=1  hl=4 l=1464 cons:  SEQUENCE
    8:d=2  hl=2 l=   9 prim:   OBJECT            :pkcs7-data
   19:d=2  hl=4 l=1449 cons:   cont [ 0 ]
   23:d=3  hl=4 l=1445 prim:    OCTET STRING      [HEX DUMP]:308205A1[REDACTED]
 1472:d=1  hl=4 l= 884 cons:  SEQUENCE
 1476:d=2  hl=2 l=   9 prim:   OBJECT            :pkcs7-encryptedData
 1487:d=2  hl=4 l= 869 cons:   cont [ 0 ]
 1491:d=3  hl=4 l= 865 cons:    SEQUENCE
 1495:d=4  hl=2 l=   1 prim:     INTEGER           :00
 1498:d=4  hl=4 l= 858 cons:     SEQUENCE
 1502:d=5  hl=2 l=   9 prim:      OBJECT            :pkcs7-data
 1513:d=5  hl=2 l=  41 cons:      SEQUENCE
 1515:d=6  hl=2 l=  10 prim:       OBJECT            :pbeWithSHA1And40BitRC2-CBC
 1527:d=6  hl=2 l=  27 cons:       SEQUENCE
 1529:d=7  hl=2 l=  20 prim:        OCTET STRING      [HEX DUMP]:B74DD380AAF9CBE6A327F74BC93C688A5E690AC2
 1551:d=7  hl=2 l=   3 prim:        INTEGER           :C350
 1556:d=5  hl=4 l= 800 prim:      cont [ 0 ]

This has two 'bags': the Data at 30+4 actually contains the ShroudedKeyBag and the EncryptedData at 30+1472 is the cert bag, which is standard and I ignore. Breaking down the ShroudedKeyBag:

$ openssl asn1parse -in test.p12 -inform der -i -strparse 57
    0:d=0  hl=4 l=1441 cons: SEQUENCE
    4:d=1  hl=4 l=1437 cons:  SEQUENCE
    8:d=2  hl=2 l=  11 prim:   OBJECT            :pkcs8ShroudedKeyBag
   21:d=2  hl=4 l=1358 cons:   cont [ 0 ]
   25:d=3  hl=4 l=1354 cons:    SEQUENCE
   29:d=4  hl=2 l= 116 cons:     SEQUENCE
   31:d=5  hl=2 l=   9 prim:      OBJECT            :PBES2
   42:d=5  hl=2 l= 103 cons:      SEQUENCE
   44:d=6  hl=2 l=   9 prim:       OBJECT            :PBES2
   55:d=6  hl=2 l=  90 cons:       SEQUENCE
   57:d=7  hl=2 l=  57 cons:        SEQUENCE
   59:d=8  hl=2 l=   9 prim:         OBJECT            :PBKDF2
   70:d=8  hl=2 l=  44 cons:         SEQUENCE
   72:d=9  hl=2 l=  20 prim:          OCTET STRING      [HEX DUMP]:547DFCB4975830F2A455BE611128B2188BB237E
   94:d=9  hl=2 l=   3 prim:          INTEGER           :0186A0
   99:d=9  hl=2 l=   1 prim:          INTEGER           :20
  102:d=9  hl=2 l=  12 cons:          SEQUENCE
  104:d=10 hl=2 l=   8 prim:           OBJECT            :hmacWithSHA256
  114:d=10 hl=2 l=   0 prim:           NULL
  116:d=7  hl=2 l=  29 cons:        SEQUENCE
  118:d=8  hl=2 l=   9 prim:         OBJECT            :aes-256-cbc
  129:d=8  hl=2 l=  16 prim:         OCTET STRING      [HEX DUMP]:12A6696B879EFB885F7C979904314FC
  147:d=4  hl=4 l=1232 prim:     OCTET STRING      [HEX DUMP]:[REDACTED]
 1383:d=2  hl=2 l=  60 cons:   SET
 1385:d=3  hl=2 l=  23 cons:    SEQUENCE
 1387:d=4  hl=2 l=   9 prim:     OBJECT            :friendlyName
 1398:d=4  hl=2 l=  10 cons:     SET
 1400:d=5  hl=2 l=   8 prim:      BMPSTRING
 1410:d=3  hl=2 l=  33 cons:    SEQUENCE
 1412:d=4  hl=2 l=   9 prim:     OBJECT            :localKeyID
 1423:d=4  hl=2 l=  20 cons:     SET
 1425:d=5  hl=2 l=  18 prim:      OCTET STRING      :Time 1530821849299

The value (ignoring the attributes, which look okay) of a ShroudedKeyBag (4.2 and 4.2.2) should be a PKCS8 EncryptedPrivateKeyInfo from rfc 5208 section 6 :

  EncryptedPrivateKeyInfo ::= SEQUENCE {
    encryptionAlgorithm  EncryptionAlgorithmIdentifier,
    encryptedData        EncryptedData }
  EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
  EncryptedData ::= OCTET STRING

And since the identified algorithm is PBES2, its parameters at 30+27+42 should be PBES2-params from rfc2898 appendix A.4 :

PBES2-params ::= SEQUENCE {
   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }

However, you can see what is actually present there is a SEQUENCE containing (OID) PBES2 and the correct PBES2-params structure, ie it is nested a level too deep . It appears something actually constructed the PBES2 AlgorithmIdentifier and then used it as the parameters of a second PBES2 AlgorithmIdentifier, which is wrong.

However, since the intent is clear, we can (manually) compute PBKDF2 salt=547DFCB49758030F2A455BE611128B2188BB237E iter=100000 size=32 alg=hmacSHA256 of pass=test giving key 2E896C4F2D9549FD D2BE8B8F895D7C56 DD9008A6D7B7196E 1A30000F7F545B37 and use that with AES-256-CBC (with PKCS7padding) IV=12A6696B879EFCB885F7C979904314FC to decrypt the RSA key:

$ dd if=test.p12 bs=1 skip=208 count=1232 | \
> openssl aes-256-cbc -d -K 2E896C4F2D9549FDD2BE8B8F895D7C56DD9008A6D7B7196E1A30000F7F545B37 -iv 12A6696B879EFCB885F7C979904314FC >test.out
$ openssl pkey -in test.out -inform der -text -noout 
Private-Key: (2048 bit)
modulus:
    00:d5:a7:ef:74:dd:ab:60:12:69:0d:dd:29:61:f7:
    0b:46:27:8d:c6:c3:5c:a6:b0:0e:59:01:d3:ff:65:
[rest redacted]

Since the cert bag is correctly formatted (and encrypted), it can be read with simply:

$ openssl pkcs12 -in test.p12 -passin pass:test -nokeys
MAC verified OK
Bag Attributes
    friendlyName: test
    localKeyID: 54 69 6D 65 20 31 35 33 30 38 32 31 38 34 39 32 39 39
subject=/CN=test
issuer=/CN=test
-----BEGIN CERTIFICATE-----
MIICrDCCAZSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0
MB4XDTE4MDcwNTIwMTcyOVoXDTE5MDcwNTIwMTcyOVowDzENMAsGA1UEAwwEdGVz
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANWn73Tdq2ASaQ3dKWH3
C0YnjcbDXKawDlkB0/9l53T4kQgy/CCsCPbv+LpcOLWIw61rPVzjlWTmg384GqAF
s7Ewn98v8JsxKw7HXeYCvw+li2x3Y+DVtkqWchnsJWnmksXAynQnrhb2ayczM+YR
OGli0Yvs6pQKNDuRKXrL2/cX212wFC42QE0NxfSblUdxrl2x4INqg9ME0fsHc2TO
lt3JItxGK7vQkU/tNIOlhKOWUxt9lVPNaIGFW0w2CkGxV1HYGRy8VCDqAfsI4x18
4WJTPTXjQ+EMl1yu5jPuRNdt7Gzvhll9O6LRUsJ2fNXAeQl7wOG/xZ9Rf73q1aTp
CBECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA
UL2dfILp69CBPF8DD8Pzso6QIcMDtBltXumv2/NL/YO1SXY3Rt3LZ4EJtrYvb/H3
E3fH8qT9Yhfcrz+0F1aFt0WCdcOWDtZ5s7pn36a3Wye9LoBjPcB36BttzaBku+49
PIOQwQGjc6vg3prFS/OBOpWsa94GZemI4xpfwHE2EXANKN4ufb9fyPRyrXGR8SQD
3EdejRwLuICvxS/u8wO4+SfiHGLuR/i+w74nQeMsyrphWtPs9cDe4NMMN0I6WGKA
u9XeWzxSmEswYmmm2y/KX+fVmeNoKbht5Oiaej9aVFS77hT/OdjO281R/1osIdPi
8EJw1sCq5Tk7jkWxxZh+6Q==
-----END CERTIFICATE-----

QEF.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM