readium / readium-lcp-server

Repository for the Readium LCP Server
BSD 3-Clause "New" or "Revised" License
73 stars 57 forks source link

generated SHA256 ECDSA signature size is 139, client side expects 132 #116

Closed danielweck closed 7 years ago

danielweck commented 7 years ago

Client-side Crypto++ lib uses secp521r1 which is size 132: https://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Message_Verification

Server-side Go code generates size 139: https://github.com/readium/readium-lcp-server/blob/feature/shiny-frontend/sign/sign.go#L55

// Used to fill the resulting output according to the XMLDSIG spec
func copyWithLeftPad(dest, src []byte) {
    numPaddingBytes := len(dest) - len(src)
    for i := 0; i < numPaddingBytes; i++ {
        dest[i] = 0
    }
    copy(dest[numPaddingBytes:], src)
}

func (signer *ecdsaSigner) Sign(in interface{}) (sig Signature, err error) {
    plain, err := Canon(in)
    if err != nil {
        return
    }

    hashed := sha256.Sum256(plain)
    r, s, err := ecdsa.Sign(rand.Reader, signer.key, hashed[:])
    if err != nil {
        return
    }

    curveSizeInBytes := int(math.Ceil(float64(signer.key.Curve.Params().BitSize) / 8))

    // The resulting signature is the concatenation of the big-endian octet strings
    // of the r and s parameters, each padded to the byte size of the curve order.
    sig.Value = make([]byte, 2*curveSizeInBytes)
    copyWithLeftPad(sig.Value[0:curveSizeInBytes], r.Bytes())
    copyWithLeftPad(sig.Value[curveSizeInBytes:], s.Bytes())

    sig.Algorithm = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
    sig.Certificate = signer.cert.Certificate[0]
    return
}
danielweck commented 7 years ago

The test certificate is p521 elliptical curve algorithm.

danielweck commented 7 years ago

The client side CryptoPP code fails at: https://github.com/readium/readium-lcp-client/blob/develop/src/lcp-client-lib/Certificate.cpp#L253

        // 139
        int s1 = m_rootSignature.size();

        // https://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Message_Verification
        // 132 secp521r1
        int s2 = rootVerifierPtr->SignatureLength();

        if (s1 != s2)
        {
            throw StatusException(Status(StatusCode::ErrorOpeningContentProviderCertificateNotValid, "ErrorOpeningContentProviderCertificateNotValid"));
        }

and of course at the actual verifier that follows:

        return rootVerifierPtr->VerifyMessage(
            m_toBeSignedData.data(),
            m_toBeSignedData.size(),
            m_rootSignature.data(),
            m_rootSignature.size()
            );
danielweck commented 7 years ago

@RemiBauzac @jpbougie @drminside @mmenu-mantano @jmgeffroy any idea?

jpbougie commented 7 years ago

I have a hard time believing the signature is 139 bytes as it should be at least an even number. Here's a token example using a new P521 key, which does produce a 132-byte signature. https://play.golang.org/p/BM823dPWZG

Do you have the sample LCPL file so I can inspect it?

danielweck commented 7 years ago

Thanks @jpbougie It is very strange indeed.

It could also be erroneous usage of C++ CryptoPP APIs on the client side. The signature is extracted here: (what really matters is the correct cert parsing sequence, which the following lines of code are part of) https://github.com/readium/readium-lcp-client/blob/develop/src/lcp-client-lib/Certificate.cpp#L141

            unsigned int unused = 0;
            BERDecodeBitString(cert, m_rootSignature, unused);

...and the signature length is checked here: https://github.com/readium/readium-lcp-client/blob/develop/src/lcp-client-lib/Certificate.cpp#L253

        // 139
        int s1 = m_rootSignature.size();
danielweck commented 7 years ago

Sample LCP license signed with SHA256-ECDSA (as generated by the Go server, based on p521 certs provided by Remi):

{"provider":"provider","id":"6ff4dc3f-6bda-428f-838e-5f17eb29cd4c","issued":"2017-02-02T15:09:26.539076623Z","encryption":{"profile":"http://readium.org/lcp/profile-1.0","content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"WFp8FIMXU2+hoCclnlDnnU3SBAIClBtGvfwP2azbCyu8hf07HO8f9TK0vNGfjJJMlTm1yxsddO+aurus5setHw=="},"user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","text_hint":"Enter your passphrase","key_check":"v4tWpYam0lgg97hF3RMgvvu+752PB1Ob5a67nalEBnaWm58mmAOEpY4LsocXuIDLmxqUUnZH7KTDUbhXrxDy+g==","value":"7E8tuzsUAJVVDJr7u2m11v2egUudqC+tCzTp/L5W8cs="}},"links":[{"rel":"hint","href":"http://192.168.1.67:8989/hint"},{"rel":"publication","href":"http://192.168.1.67:8989/contents/d15f0baf-bbfa-453d-9d81-981a836c8721","type":"application/epub+zip","title":"wasted","length":752496,"hash":"95c18f2539b357d00e48c73fda494fb77b92ac4568cb86abfa7408d4b17192dd"},{"rel":"status","href":"http://192.168.1.67:8990/licenses/6ff4dc3f-6bda-428f-838e-5f17eb29cd4c/status","type":"application/vnd.readium.license.status.v1.0+json"}],"user":{"id":"66a159af-9780-4736-a0bb-c74ee466fbc5","email":"QkQf8v94WbO2nIZIWEF8/zBNyEuiHZvUz0oseBFBA2HIRyCMEGJ8h8RR3gMz75qX","name":"5Xp78+FS44+dmm3JhHFD0OsbLoaSF2poTUsoddmTL18=","encrypted":["email","name"]},"rights":{"print":100,"copy":2048},"signature":{"certificate":"MIICdjCCAdigAwIBAgIBATAJBgcqhkjOPQQBMFQxCzAJBgNVBAYTAkZSMQ4wDAYDVQQHEwVQYXJpczEPMA0GA1UEChMGRURSTGFiMRQwEgYDVQQLEwtSZWFkaXVtIExDUDEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwMTMxMDkzNTE5WhcNMjcwMTI5MDkzNTE5WjB7MQswCQYDVQQGEwJGUjEOMAwGA1UEBxMFUGFyaXMxDzANBgNVBAoTBkVEUkxhYjEUMBIGA1UECxMLUmVhZGl1bSBMQ1AxDzANBgNVBAMTBkRhbmllbDEkMCIGCSqGSIb3DQEJARYVZGFuaWVsLndlY2tAZ21haWwuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBCFaAA6vSC1pTjr6kbL00Ssb/YeViz03NwZeMFPLFt9jMBMExeYsu1h3Q+MKFHfa3+yiKg/lB77/6smpR7Au7NXsAOEtPqyce8YZckpLGaAIr/i+2d6NmpxdiQ09PYt+JnTZCpumQytsQnFTfGPPnIb3XlyeLn7TJjzCzOu9c6+MciSGjMjAwMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAkGByqGSM49BAEDgYwAMIGIAkIB3U1AaHDVCXTyRqi0fPtZryBNWuGuVomzycvSbM3jmCBXixgN99OgFZyFFf+l3G4jH6a7tTq/+EZkmIKSqsFNTL8CQgG9eaDyyEAbUppoJoNRThxB73kjZ4XtLfeW9opT8kdIe2VJg17BFkYPZ4h8MoVzJS/blO0HW9VmdhInd47Tm4FzVw==","value":"AfbiKzhHKwI143vCkf8wBSuXz18dVps/A81haKw/7GrzF9Zxm46gOsxqkqV4lf7YyIS3IJTVecqPwIb+TkmloPtvAJaKuudrlzpxEGw63+uAcaPlZau9IiKqCPSGK78WmxRjXc3X/XmLK1HfKiDv8Z/+5UmLsMotAfwkhMeU6TdhKoyS","algorithm":"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}}
danielweck commented 7 years ago

Just to be clear: m_rootSignature above is extracted from the provider certificate.

danielweck commented 7 years ago

In hindsight, I should have posted this issue in readium-lcp-client, as this probably has more to do with how the LCP lib + CryptoPP parse the provider certificate, which unfortunately fails to validate against the root certificate:

bool Certificate::VerifyCertificate(ICertificate * rootCertificate) https://github.com/readium/readium-lcp-client/blob/develop/src/lcp-client-lib/Certificate.cpp#L214

So either the provider certificate injected by the Go server in LCP licenses is wrong, or the client parser is not written correctly: https://github.com/readium/readium-lcp-client/blob/develop/src/lcp-client-lib/Certificate.cpp#L63 (note that the same code works for RSA, it's just ECDSA that fails)

RemiBauzac commented 7 years ago

Hum, I'm testing your license (provided above) with my OpenSSL client piece of code. It fails too. I'm investigating...

danielweck commented 7 years ago

The signature>certificate from the above JSON LCP license matches exactly cert.pem which is used by the Go server. So clearly the Go server does not have a bug.

jpbougie commented 7 years ago

Oh yes, so forget my previous code example. It does seem like the Public certificate indeed has a 139-byte signature and is signed using ECDSA-SHA1: https://play.golang.org/p/9k0BJWf3ld

danielweck commented 7 years ago

Indeed, I am updating the Java validator utility to support ECDSA, and I see SHA1withECDSA :)

danielweck commented 7 years ago

FYI, the Java LCPL checker is here: https://github.com/edrlab/lcp-testing-tools/tree/master/SignatureVerifier_Java

RemiBauzac commented 7 years ago

I did a test with the sample ECDSA certificates (embedded into the sources) and the result is the same. @jpbougie did you have a working client implementation somewhere ?

danielweck commented 7 years ago

@RemiBauzac do you have ECDSA certs signed with SHA256 instead of SHA1? I'm sure you have plenty of command line utilities already, but you can try this signature checker written in Java: run.sh "PATH_TO/cacert.pem" "PATH_TO/license.lcpl" verbose https://github.com/edrlab/lcp-testing-tools/tree/master/SignatureVerifier_Java (the CLI dumps plenty of useful info when the verbose parameter is set)

RemiBauzac commented 7 years ago

OK, I had tried it yesterday with no success. I retry today.

RemiBauzac commented 7 years ago

@danielweck I have a huge problem with the JAVA tool, because it says to me that the signature license signature is checked against the Root certificate : it's false.

Here is the verbose mode:

----------------------------------------------------------
Root certificate from [/Users/rbauzac/Dev/TEA/Tools/CA/generic/cacert.pem]:
[
[
  Version: V3
  Subject: CN=My CA, OU=Readium LCP, O=EDRLab, L=Paris, C=FR
  Signature Algorithm: SHA1withECDSA, OID = 1.2.840.10045.4.1

  Key:  Sun EC public key, 521 bits
  public x coord: 211174653557851890031819209681144588233289163509616210474817140933640582953834732591512892179757171623292617281294299299549694113491960218411158800760374744
  public y coord: 2947219561471802752843490529521139655474863481695976830224153113163604008368153818223342165852702111847284519545962902418667534958937845265318417781787000751
  parameters: secp521r1 [NIST P-521] (1.3.132.0.35)
  Validity: [From: Tue Jan 31 10:33:19 CET 2017,
               To: Mon Jan 18 10:33:19 CET 2038]
  Issuer: CN=My CA, OU=Readium LCP, O=EDRLab, L=Paris, C=FR
  SerialNumber: [    92fcfccb c3b15083]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:0
]

]
  Algorithm: [SHA1withECDSA]
  Signature:
0000: 30 81 88 02 42 01 1A 09   F0 C4 AC E7 3F 52 DD 32  0...B.......?R.2
0010: A0 DF 4C 23 6B CA 49 2F   48 AD CE 6E 8A 70 A5 6B  ..L#k.I/H..n.p.k
0020: 3E F4 79 79 85 A0 A9 B6   C2 86 C2 5E DF A1 8C 0F  >.yy.......^....
0030: C3 67 B8 A1 17 FF CF B5   9F 1B C0 E2 DE 29 37 F4  .g...........)7.
0040: 1F 03 52 CE 89 F5 3A 02   42 00 80 51 E2 CF AF 44  ..R...:.B..Q...D
0050: 9C B5 CD 28 2A A5 AE E0   C2 73 29 2A 34 5B 38 B7  ...(*....s)*4[8.
0060: 38 85 9B 47 68 6C 92 77   43 8D 64 B0 7B 5C C3 C4  8..Ghl.wC.d..\..
0070: A8 EF 04 DA AF 5D A6 36   D4 46 B2 49 3C CB DB 94  .....].6.F.I<...
0080: 39 5D A2 7D B4 92 85 F3   B4 DF 77                 9]........w

]
----------------------------------------------------------

----------------------------------------------------------
LCP license JSON [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
{"provider":"www.tea-ebook.com/lcp-1.0","id":"7ea400cf-caf3-4382-93ef-e3384e5a9341","issued":"2017-02-02T16:06:10.0741421Z","encryption":{"profile":"http://readium.org/lcp/profile-1.0","content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"UIoC3QtM/hy7FlSt41bxSY7VbUPOIEMnE3/XGWjviJEQ2EwRxfifLqO7zWX5iD827eDDqqe/dx6YEumKeOzAWw=="},"user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","text_hint":"Enter passphrase","key_check":"dSR8eVheCRxOH39gGYWtRJmKn1/RVAHVFUjb/suEl3ZG+qbozgq+IOMJ6uh2kDnFDWz2rbRMQB8rrVFuLpkDBg=="}},"links":[{"rel":"hint","href":"http://example.com/hint"},{"rel":"publication","href":"http://readium-lcp-server:8989/contents/8434257393e3cb5eaac45fed0d0d07bca1017719b728b7494af840d762a877ef","type":"application/epub+zip","title":"alcools.epub","length":60762,"hash":"88307482b1d6a2d7f584649701c7d99cbd49f432399145f6e99cd23b779e1784"},{"rel":"status","href":"http://readium-lsd-server:8990/licenses/7ea400cf-caf3-4382-93ef-e3384e5a9341/status","type":"application/vnd.readium.license.status.v1.0+json"}],"user":{"id":"rbauzac","email":"rbauzac@tea-ebook.com"},"rights":{"print":10,"copy":2048,"start":"2016-09-01T01:08:15+01:00","end":"2016-11-25T01:08:15+01:00"},"signature":{"certificate":"MIICdjCCAdigAwIBAgIBATAJBgcqhkjOPQQBMFQxCzAJBgNVBAYTAkZSMQ4wDAYDVQQHEwVQYXJpczEPMA0GA1UEChMGRURSTGFiMRQwEgYDVQQLEwtSZWFkaXVtIExDUDEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwMTMxMDkzNTE5WhcNMjcwMTI5MDkzNTE5WjB7MQswCQYDVQQGEwJGUjEOMAwGA1UEBxMFUGFyaXMxDzANBgNVBAoTBkVEUkxhYjEUMBIGA1UECxMLUmVhZGl1bSBMQ1AxDzANBgNVBAMTBkRhbmllbDEkMCIGCSqGSIb3DQEJARYVZGFuaWVsLndlY2tAZ21haWwuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBCFaAA6vSC1pTjr6kbL00Ssb/YeViz03NwZeMFPLFt9jMBMExeYsu1h3Q+MKFHfa3+yiKg/lB77/6smpR7Au7NXsAOEtPqyce8YZckpLGaAIr/i+2d6NmpxdiQ09PYt+JnTZCpumQytsQnFTfGPPnIb3XlyeLn7TJjzCzOu9c6+MciSGjMjAwMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAkGByqGSM49BAEDgYwAMIGIAkIB3U1AaHDVCXTyRqi0fPtZryBNWuGuVomzycvSbM3jmCBXixgN99OgFZyFFf+l3G4jH6a7tTq/+EZkmIKSqsFNTL8CQgG9eaDyyEAbUppoJoNRThxB73kjZ4XtLfeW9opT8kdIe2VJg17BFkYPZ4h8MoVzJS/blO0HW9VmdhInd47Tm4FzVw==","value":"AMhCM21PLWpBhczNes0o2iT1Olad+VLc56JWQO9+bhFCB/Re1mztZoWxM1odSv96NkjXMkFOywk3Q/VIdUzsrwFnALqhRewYfZdyXsC7CFRB2ixTIxKnqYks0u+4tRLYUIW7+WJluhDZ+1kE6lbkiDOt0P11ZO/yJPDhvVKgjp/JK3su","algorithm":"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}}

----------------------------------------------------------

----------------------------------------------------------
LCP signature algorithm URI from [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
----------------------------------------------------------

----------------------------------------------------------
LCP signature from [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
AMhCM21PLWpBhczNes0o2iT1Olad+VLc56JWQO9+bhFCB/Re1mztZoWxM1odSv96NkjXMkFOywk3Q/VIdUzsrwFnALqhRewYfZdyXsC7CFRB2ixTIxKnqYks0u+4tRLYUIW7+WJluhDZ+1kE6lbkiDOt0P11ZO/yJPDhvVKgjp/JK3su
----------------------------------------------------------

----------------------------------------------------------
LCP provider certificate (base64) from [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
MIICdjCCAdigAwIBAgIBATAJBgcqhkjOPQQBMFQxCzAJBgNVBAYTAkZSMQ4wDAYDVQQHEwVQYXJpczEPMA0GA1UEChMGRURSTGFiMRQwEgYDVQQLEwtSZWFkaXVtIExDUDEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwMTMxMDkzNTE5WhcNMjcwMTI5MDkzNTE5WjB7MQswCQYDVQQGEwJGUjEOMAwGA1UEBxMFUGFyaXMxDzANBgNVBAoTBkVEUkxhYjEUMBIGA1UECxMLUmVhZGl1bSBMQ1AxDzANBgNVBAMTBkRhbmllbDEkMCIGCSqGSIb3DQEJARYVZGFuaWVsLndlY2tAZ21haWwuY29tMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBCFaAA6vSC1pTjr6kbL00Ssb/YeViz03NwZeMFPLFt9jMBMExeYsu1h3Q+MKFHfa3+yiKg/lB77/6smpR7Au7NXsAOEtPqyce8YZckpLGaAIr/i+2d6NmpxdiQ09PYt+JnTZCpumQytsQnFTfGPPnIb3XlyeLn7TJjzCzOu9c6+MciSGjMjAwMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAkGByqGSM49BAEDgYwAMIGIAkIB3U1AaHDVCXTyRqi0fPtZryBNWuGuVomzycvSbM3jmCBXixgN99OgFZyFFf+l3G4jH6a7tTq/+EZkmIKSqsFNTL8CQgG9eaDyyEAbUppoJoNRThxB73kjZ4XtLfeW9opT8kdIe2VJg17BFkYPZ4h8MoVzJS/blO0HW9VmdhInd47Tm4FzVw==
----------------------------------------------------------

----------------------------------------------------------
LCP license JSON, without signature [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
{"provider":"www.tea-ebook.com/lcp-1.0","id":"7ea400cf-caf3-4382-93ef-e3384e5a9341","issued":"2017-02-02T16:06:10.0741421Z","encryption":{"profile":"http://readium.org/lcp/profile-1.0","content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"UIoC3QtM/hy7FlSt41bxSY7VbUPOIEMnE3/XGWjviJEQ2EwRxfifLqO7zWX5iD827eDDqqe/dx6YEumKeOzAWw=="},"user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","text_hint":"Enter passphrase","key_check":"dSR8eVheCRxOH39gGYWtRJmKn1/RVAHVFUjb/suEl3ZG+qbozgq+IOMJ6uh2kDnFDWz2rbRMQB8rrVFuLpkDBg=="}},"links":[{"rel":"hint","href":"http://example.com/hint"},{"rel":"publication","href":"http://readium-lcp-server:8989/contents/8434257393e3cb5eaac45fed0d0d07bca1017719b728b7494af840d762a877ef","type":"application/epub+zip","title":"alcools.epub","length":60762,"hash":"88307482b1d6a2d7f584649701c7d99cbd49f432399145f6e99cd23b779e1784"},{"rel":"status","href":"http://readium-lsd-server:8990/licenses/7ea400cf-caf3-4382-93ef-e3384e5a9341/status","type":"application/vnd.readium.license.status.v1.0+json"}],"user":{"id":"rbauzac","email":"rbauzac@tea-ebook.com"},"rights":{"print":10,"copy":2048,"start":"2016-09-01T01:08:15+01:00","end":"2016-11-25T01:08:15+01:00"}}
----------------------------------------------------------

----------------------------------------------------------
LCP license canonical JSON [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
{"encryption":{"content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"UIoC3QtM/hy7FlSt41bxSY7VbUPOIEMnE3/XGWjviJEQ2EwRxfifLqO7zWX5iD827eDDqqe/dx6YEumKeOzAWw=="},"profile":"http://readium.org/lcp/profile-1.0","user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","key_check":"dSR8eVheCRxOH39gGYWtRJmKn1/RVAHVFUjb/suEl3ZG+qbozgq+IOMJ6uh2kDnFDWz2rbRMQB8rrVFuLpkDBg==","text_hint":"Enter passphrase"}},"id":"7ea400cf-caf3-4382-93ef-e3384e5a9341","issued":"2017-02-02T16:06:10.0741421Z","links":[{"href":"http://example.com/hint","rel":"hint"},{"hash":"88307482b1d6a2d7f584649701c7d99cbd49f432399145f6e99cd23b779e1784","href":"http://readium-lcp-server:8989/contents/8434257393e3cb5eaac45fed0d0d07bca1017719b728b7494af840d762a877ef","length":60762,"rel":"publication","title":"alcools.epub","type":"application/epub+zip"},{"href":"http://readium-lsd-server:8990/licenses/7ea400cf-caf3-4382-93ef-e3384e5a9341/status","rel":"status","type":"application/vnd.readium.license.status.v1.0+json"}],"provider":"www.tea-ebook.com/lcp-1.0","rights":{"copy":2048,"end":"2016-11-25T01:08:15+01:00","print":10,"start":"2016-09-01T01:08:15+01:00"},"user":{"email":"rbauzac@tea-ebook.com","id":"rbauzac"}}
----------------------------------------------------------

----------------------------------------------------------
Provider certificate from [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl]:
[
[
  Version: V3
  Subject: EMAILADDRESS=daniel.weck@gmail.com, CN=Daniel, OU=Readium LCP, O=EDRLab, L=Paris, C=FR
  Signature Algorithm: SHA1withECDSA, OID = 1.2.840.10045.4.1

  Key:  Sun EC public key, 521 bits
  public x coord: 3544191669040057133522264741111739182237381753730129411361884130268643036679219491661254462339637952141473694583806400070703825388960878092047075112444966267
  public y coord: 754781611952177361843580245191696459669336391858191347807447540271660840936589318754642579248639509841404110822624006436850281845818767579456144320816253217
  parameters: secp521r1 [NIST P-521] (1.3.132.0.35)
  Validity: [From: Tue Jan 31 10:35:19 CET 2017,
               To: Fri Jan 29 10:35:19 CET 2027]
  Issuer: CN=My CA, OU=Readium LCP, O=EDRLab, L=Paris, C=FR
  SerialNumber: [    01]

Certificate Extensions: 3
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[2]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[3]: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

]
  Algorithm: [SHA1withECDSA]
  Signature:
0000: 30 81 88 02 42 01 DD 4D   40 68 70 D5 09 74 F2 46  0...B..M@hp..t.F
0010: A8 B4 7C FB 59 AF 20 4D   5A E1 AE 56 89 B3 C9 CB  ....Y. MZ..V....
0020: D2 6C CD E3 98 20 57 8B   18 0D F7 D3 A0 15 9C 85  .l... W.........
0030: 15 FF A5 DC 6E 23 1F A6   BB B5 3A BF F8 46 64 98  ....n#....:..Fd.
0040: 82 92 AA C1 4D 4C BF 02   42 01 BD 79 A0 F2 C8 40  ....ML..B..y...@
0050: 1B 52 9A 68 26 83 51 4E   1C 41 EF 79 23 67 85 ED  .R.h&.QN.A.y#g..
0060: 2D F7 96 F6 8A 53 F2 47   48 7B 65 49 83 5E C1 16  -....S.GH.eI.^..
0070: 46 0F 67 88 7C 32 85 73   25 2F DB 94 ED 07 5B D5  F.g..2.s%/....[.
0080: 66 76 12 27 77 8E D3 9B   81 73 57                 fv.'w....sW

]
----------------------------------------------------------

----------------------------------------------------------
Succesfully verified the provider certificate from [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl] against the root certificate from [/Users/rbauzac/Dev/TEA/Tools/CA/generic/cacert.pem] using public key [Sun EC public key, 521 bits
  public x coord: 211174653557851890031819209681144588233289163509616210474817140933640582953834732591512892179757171623292617281294299299549694113491960218411158800760374744
  public y coord: 2947219561471802752843490529521139655474863481695976830224153113163604008368153818223342165852702111847284519545962902418667534958937845265318417781787000751
  parameters: secp521r1 [NIST P-521] (1.3.132.0.35)].

----------------------------------------------------------

### Problem verifying the LCP signature for [/Users/rbauzac/Dev/Readium/lcp-testing-tools/SignatureVerifier_Java/./license.lcpl] against the root certificate from [/Users/rbauzac/Dev/TEA/Tools/CA/generic/cacert.pem].
RemiBauzac commented 7 years ago

OK, this is a simple messaging problem. Fixed on the tool, I will sent a Pull request soon.

danielweck commented 7 years ago

@RemiBauzac oh yes, I improved the error message. Thank you!

danielweck commented 7 years ago

@RemiBauzac I tried the new SHA256-ECDSA certificates you created, thank you. I generated a LCPL from the latest Go server code (branch feature/shiny-frontend). Unfortunately the signature does not validate with the Java tool (I will try with the Crypto++ Android client). The Java lib emits the error "Could not verify signature" (I observed the same message with your LCPL earlier today, but I wanted to create my own, just to make sure)

 ./run.sh "/Users/danielweck/Code/_DATA/LCP-Go-server/Certs/ECDSA/cacert.pem" "/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl" verbose
mkdir: out: File exists

####################################################################
## MAX VERBOSITY ###################################################
####################################################################

----------------------------------------------------------
Root certificate from [/Users/danielweck/Code/_DATA/LCP-Go-server/Certs/ECDSA/cacert.pem]:
[
[
  Version: V3
  Subject: CN=LCP CA, OU=EDRLab, O=Readium, L=Paris, C=FR
  Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2

  Key:  Sun EC public key, 256 bits
  public x coord: 12202308545475898495535766575685470073874756770179026005570222415532776911289
  public y coord: 34419236918108317808096301880286076422468125845957887588402838276853769293599
  parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
  Validity: [From: Fri Feb 03 16:23:10 GMT 2017,
               To: Mon Jan 18 16:23:10 GMT 2038]
  Issuer: CN=LCP CA, OU=EDRLab, O=Readium, L=Paris, C=FR
  SerialNumber: [    8c186caa b428a2f3]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:0
]

]
  Algorithm: [SHA256withECDSA]
  Signature:
0000: 30 45 02 21 00 DD B1 91   6E 12 8A 9E AC D2 4F 78  0E.!....n.....Ox
0010: 60 34 C0 8F 1D CC 36 77   93 B6 DF 4C 50 4A 87 0C  `4....6w...LPJ..
0020: 22 69 C8 9A 8F 02 20 77   32 83 02 D8 C7 44 5A 0D  "i.... w2....DZ.
0030: FF 5D 42 F4 80 BC 6B 5F   37 1F 8D E7 84 06 F7 EF  .]B...k_7.......
0040: F5 EA D5 68 75 4D 8B                               ...huM.

]
----------------------------------------------------------

----------------------------------------------------------
LCP license JSON [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
{"provider":"provider","id":"37f21537-f2df-4e2f-9cc9-fba64f2a62f3","issued":"2017-02-03T19:13:16.954053132Z","encryption":{"profile":"http://readium.org/lcp/profile-1.0","content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"OYaQFztQ0bvFsiC48w9MV4JWxPqEZg/edLJc5TNZw1cmT+RIMk/luxrVFLUFIm6zE3qoa6lUd05F0fkqrZ+sGg=="},"user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","text_hint":"Enter your passphrase","key_check":"DRA6WY2kEOWCjjXNZCFLg6zcuHdQ5tW61UU5Cxx3SyAtoGuiwPijOKmWeSeOxTkk2+xFpYpfHGubq55hdsZZ6Q==","value":"7E8tuzsUAJVVDJr7u2m11v2egUudqC+tCzTp/L5W8cs="}},"links":[{"rel":"hint","href":"http://192.168.1.67:8989/hint"},{"rel":"publication","href":"http://192.168.1.67:8989/contents/0e2577bc-6344-4a4c-8a1c-7c8294b46418","type":"application/epub+zip","title":"wasteland","length":752496,"hash":"d9947e8feed47f27972bc7375bd5e6ee4224cf0c552f05b41abad6cd5bce2d34"},{"rel":"status","href":"http://192.168.1.67:8990/licenses/37f21537-f2df-4e2f-9cc9-fba64f2a62f3/status","type":"application/vnd.readium.license.status.v1.0+json"}],"user":{"id":"116db3e0-44c9-4d68-b3e2-ab20b0b25f93","email":"SxhF1rSQ4ZDpVzNF2BxmomA2KUFwwV9Bc2PQJ61zYYo=","name":"7Ro2Jit1AO3nB8cCIHR5CEnCk1rZRWWd3VT2CpiBK6w=","encrypted":["email","name"]},"rights":{"print":100,"copy":2048},"signature":{"certificate":"MIIB7zCCAZSgAwIBAgIBATAKBggqhkjOPQQDAjBRMQswCQYDVQQGEwJGUjEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB1JlYWRpdW0xDzANBgNVBAsTBkVEUkxhYjEPMA0GA1UEAxMGTENQIENBMB4XDTE3MDIwMzEyMjMxNFoXDTI3MDIwMTE2MjMxNFowfDELMAkGA1UEBhMCRlIxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdSZWFkaXVtMQ8wDQYDVQQLEwZFRFJMYWIxFDASBgNVBAMTC1Rlc3QgRGFuaWVsMSQwIgYJKoZIhvcNAQkBFhVkYW5pZWwud2Vja0BnbWFpbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASA+Zkkq4bGlw4Piw+KGqWoQpq+WdXNWlr8XPgPX5oU5aX7C2TlrG4w4j/EgoRTYKJayGA7xkJZhs3+ULsO4jzBozIwMDAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgNJADBGAiEAl3wEslW7yM4AWld0pl7FkHSz49953YSoTBqnPfbxZkMCIQCF8fYVEXjClqWCEktC77Y41rbYkLSooJgAA4KOw2JIqg==","value":"KgZk57ZmVjkMXS00b/u2asqm3am+7U7DssOiwleuwlKHYPVPKb5hgs0LUJs54ewu+l4/QpLkx+PqwIyCu2F6rg==","algorithm":"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}}

----------------------------------------------------------

----------------------------------------------------------
LCP signature algorithm URI from [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
----------------------------------------------------------

----------------------------------------------------------
LCP signature from [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
KgZk57ZmVjkMXS00b/u2asqm3am+7U7DssOiwleuwlKHYPVPKb5hgs0LUJs54ewu+l4/QpLkx+PqwIyCu2F6rg==
----------------------------------------------------------

----------------------------------------------------------
LCP provider certificate (base64) from [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
MIIB7zCCAZSgAwIBAgIBATAKBggqhkjOPQQDAjBRMQswCQYDVQQGEwJGUjEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB1JlYWRpdW0xDzANBgNVBAsTBkVEUkxhYjEPMA0GA1UEAxMGTENQIENBMB4XDTE3MDIwMzEyMjMxNFoXDTI3MDIwMTE2MjMxNFowfDELMAkGA1UEBhMCRlIxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdSZWFkaXVtMQ8wDQYDVQQLEwZFRFJMYWIxFDASBgNVBAMTC1Rlc3QgRGFuaWVsMSQwIgYJKoZIhvcNAQkBFhVkYW5pZWwud2Vja0BnbWFpbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASA+Zkkq4bGlw4Piw+KGqWoQpq+WdXNWlr8XPgPX5oU5aX7C2TlrG4w4j/EgoRTYKJayGA7xkJZhs3+ULsO4jzBozIwMDAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgNJADBGAiEAl3wEslW7yM4AWld0pl7FkHSz49953YSoTBqnPfbxZkMCIQCF8fYVEXjClqWCEktC77Y41rbYkLSooJgAA4KOw2JIqg==
----------------------------------------------------------

----------------------------------------------------------
LCP license JSON, without signature [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
{"provider":"provider","id":"37f21537-f2df-4e2f-9cc9-fba64f2a62f3","issued":"2017-02-03T19:13:16.954053132Z","encryption":{"profile":"http://readium.org/lcp/profile-1.0","content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"OYaQFztQ0bvFsiC48w9MV4JWxPqEZg/edLJc5TNZw1cmT+RIMk/luxrVFLUFIm6zE3qoa6lUd05F0fkqrZ+sGg=="},"user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","text_hint":"Enter your passphrase","key_check":"DRA6WY2kEOWCjjXNZCFLg6zcuHdQ5tW61UU5Cxx3SyAtoGuiwPijOKmWeSeOxTkk2+xFpYpfHGubq55hdsZZ6Q==","value":"7E8tuzsUAJVVDJr7u2m11v2egUudqC+tCzTp/L5W8cs="}},"links":[{"rel":"hint","href":"http://192.168.1.67:8989/hint"},{"rel":"publication","href":"http://192.168.1.67:8989/contents/0e2577bc-6344-4a4c-8a1c-7c8294b46418","type":"application/epub+zip","title":"wasteland","length":752496,"hash":"d9947e8feed47f27972bc7375bd5e6ee4224cf0c552f05b41abad6cd5bce2d34"},{"rel":"status","href":"http://192.168.1.67:8990/licenses/37f21537-f2df-4e2f-9cc9-fba64f2a62f3/status","type":"application/vnd.readium.license.status.v1.0+json"}],"user":{"id":"116db3e0-44c9-4d68-b3e2-ab20b0b25f93","email":"SxhF1rSQ4ZDpVzNF2BxmomA2KUFwwV9Bc2PQJ61zYYo=","name":"7Ro2Jit1AO3nB8cCIHR5CEnCk1rZRWWd3VT2CpiBK6w=","encrypted":["email","name"]},"rights":{"print":100,"copy":2048}}
----------------------------------------------------------

Unexpected JSON type?
email
Unexpected JSON type?
name

----------------------------------------------------------
LCP license canonical JSON [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
{"encryption":{"content_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc","encrypted_value":"OYaQFztQ0bvFsiC48w9MV4JWxPqEZg/edLJc5TNZw1cmT+RIMk/luxrVFLUFIm6zE3qoa6lUd05F0fkqrZ+sGg=="},"profile":"http://readium.org/lcp/profile-1.0","user_key":{"algorithm":"http://www.w3.org/2001/04/xmlenc#sha256","key_check":"DRA6WY2kEOWCjjXNZCFLg6zcuHdQ5tW61UU5Cxx3SyAtoGuiwPijOKmWeSeOxTkk2+xFpYpfHGubq55hdsZZ6Q==","text_hint":"Enter your passphrase","value":"7E8tuzsUAJVVDJr7u2m11v2egUudqC+tCzTp/L5W8cs="}},"id":"37f21537-f2df-4e2f-9cc9-fba64f2a62f3","issued":"2017-02-03T19:13:16.954053132Z","links":[{"href":"http://192.168.1.67:8989/hint","rel":"hint"},{"hash":"d9947e8feed47f27972bc7375bd5e6ee4224cf0c552f05b41abad6cd5bce2d34","href":"http://192.168.1.67:8989/contents/0e2577bc-6344-4a4c-8a1c-7c8294b46418","length":752496,"rel":"publication","title":"wasteland","type":"application/epub+zip"},{"href":"http://192.168.1.67:8990/licenses/37f21537-f2df-4e2f-9cc9-fba64f2a62f3/status","rel":"status","type":"application/vnd.readium.license.status.v1.0+json"}],"provider":"provider","rights":{"copy":2048,"print":100},"user":{"email":"SxhF1rSQ4ZDpVzNF2BxmomA2KUFwwV9Bc2PQJ61zYYo=","encrypted":["email","name"],"id":"116db3e0-44c9-4d68-b3e2-ab20b0b25f93","name":"7Ro2Jit1AO3nB8cCIHR5CEnCk1rZRWWd3VT2CpiBK6w="}}
----------------------------------------------------------

----------------------------------------------------------
Provider certificate from [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl]:
[
[
  Version: V3
  Subject: EMAILADDRESS=daniel.weck@gmail.com, CN=Test Daniel, OU=EDRLab, O=Readium, L=Paris, C=FR
  Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2

  Key:  Sun EC public key, 256 bits
  public x coord: 58337046493600899783447676103416682198320733090066677023326398356799916479717
  public y coord: 75075177268890258517687306354230249978859068178749400948016390317889080671425
  parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
  Validity: [From: Fri Feb 03 12:23:14 GMT 2017,
               To: Mon Feb 01 16:23:14 GMT 2027]
  Issuer: CN=LCP CA, OU=EDRLab, O=Readium, L=Paris, C=FR
  SerialNumber: [    01]

Certificate Extensions: 3
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[2]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[3]: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

]
  Algorithm: [SHA256withECDSA]
  Signature:
0000: 30 46 02 21 00 97 7C 04   B2 55 BB C8 CE 00 5A 57  0F.!.....U....ZW
0010: 74 A6 5E C5 90 74 B3 E3   DF 79 DD 84 A8 4C 1A A7  t.^..t...y...L..
0020: 3D F6 F1 66 43 02 21 00   85 F1 F6 15 11 78 C2 96  =..fC.!......x..
0030: A5 82 12 4B 42 EF B6 38   D6 B6 D8 90 B4 A8 A0 98  ...KB..8........
0040: 00 03 82 8E C3 62 48 AA                            .....bH.

]
----------------------------------------------------------

----------------------------------------------------------
Successfully verified the provider certificate from [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl] against the public key [Sun EC public key, 256 bits
  public x coord: 12202308545475898495535766575685470073874756770179026005570222415532776911289
  public y coord: 34419236918108317808096301880286076422468125845957887588402838276853769293599
  parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)] from the root certificate [/Users/danielweck/Code/_DATA/LCP-Go-server/Certs/ECDSA/cacert.pem].

----------------------------------------------------------

### Problem verifying the LCP signature for [/Users/danielweck/Code/_DATA/LCP/LCP_wasteland_ECDSA_BUY.lcpl] against the root certificate from [/Users/danielweck/Code/_DATA/LCP-Go-server/Certs/ECDSA/cacert.pem].

Could not verify signature
danielweck commented 7 years ago

Okay, on the Crypto++ Android client: The "root" certificate cacert.pem contains a public key (size 311) with which we create a CryptoPP ECDSA<ECP, SHA256>::PublicKey instance, with which we create a CryptoPP ECDSA<ECP, SHA256>::Verifier() instance, which has a SignatureLength of 64. I note that the "provider" certificate cert.pem contains a 72-long signature (compared with 71 for the root cert). The client code fails at the point when the above "verifier" (based on the root certificate's public key) attempts to check the signed message in the provider certificate. Strangely, this phase passes in the Java utility. mhmm..

danielweck commented 7 years ago

Even more weird, where the Java utility fails, the client CryptoPP Android app succeeds! (verification of the actual canonical LCP signature, based on the root cert)

danielweck commented 7 years ago

In the Java verifier, using the default crypto provider I get the following error:

Could not verify signature
java.security.SignatureException: Could not verify signature
    at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:320)
    at java.security.Signature$Delegate.engineVerify(Signature.java:1219)
    at java.security.Signature.verify(Signature.java:652)
    at LcpLicenseSignatureVerifier.verifyLcpSignature(LcpLicenseSignatureVerifier.java:325)
    at LcpLicenseSignatureVerifier.verify(LcpLicenseSignatureVerifier.java:413)
    at LcpLicenseSignatureVerifier.main(LcpLicenseSignatureVerifier.java:471)
Caused by: java.security.SignatureException: Could not decode signature
    at sun.security.ec.ECDSASignature.decodeSignature(ECDSASignature.java:386)
    at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:317)
    ... 5 more
Caused by: java.io.IOException: Sequence tag error
    at sun.security.util.DerInputStream.getSequence(DerInputStream.java:297)
    at sun.security.ec.ECDSASignature.decodeSignature(ECDSASignature.java:370)
    ... 6 more

...whereas with the BouncyCastle provider I get:

error decoding signature bytes.
java.security.SignatureException: error decoding signature bytes.
    at org.bouncycastle.jcajce.provider.asymmetric.util.DSABase.engineVerify(Unknown Source)
    at java.security.Signature$Delegate.engineVerify(Signature.java:1219)
    at java.security.Signature.verify(Signature.java:652)
    at LcpLicenseSignatureVerifier.verifyLcpSignature(LcpLicenseSignatureVerifier.java:325)
    at LcpLicenseSignatureVerifier.verify(LcpLicenseSignatureVerifier.java:413)
    at LcpLicenseSignatureVerifier.main(LcpLicenseSignatureVerifier.java:471)
danielweck commented 7 years ago

Ah, it looks like this has something to do with DER ASN-1 encoding.

danielweck commented 7 years ago

I fixed the Java checker (the LCP signature needed to be formatted with DER ASN.1 before passing into the SHA256 ECDSA verifier): https://github.com/edrlab/lcp-testing-tools/commit/c1162bc5951a8779da6ce33163055876872b6c63

I also added an additional CLI parameter to specify the BouncyCastle crypto provider (instead of the default Sun ones): https://github.com/edrlab/lcp-testing-tools/tree/master/SignatureVerifier_Java

Now I need to figure-out why the Crypto++ Android client app fails to validate the certificate itself. My guess is: I have to convert the 71/72 bytes DER ASN.1 provider certificate signature to a 64 bytes format the verifier expects.

danielweck commented 7 years ago

Okay, I fixed the Crypto++ client app. It turns out DSASignatureFormat::DSA_P1363 is used internally by the verifier (64 bytes long sigs), so I just converted the DSASignatureFormat::DSA_DER byte array (as included in the provider certificate) to the correct format: https://github.com/readium/readium-lcp-client/commit/290545d39eb080d09dcaa6761072d2d9e499f793