Closed danielweck closed 7 years ago
The test certificate is p521
elliptical curve algorithm.
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()
);
@RemiBauzac @jpbougie @drminside @mmenu-mantano @jmgeffroy any idea?
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?
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();
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"}}
Just to be clear: m_rootSignature
above is extracted from the provider certificate.
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)
Hum, I'm testing your license (provided above) with my OpenSSL client piece of code. It fails too. I'm investigating...
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.
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
Indeed, I am updating the Java validator utility to support ECDSA, and I see SHA1withECDSA
:)
FYI, the Java LCPL checker is here: https://github.com/edrlab/lcp-testing-tools/tree/master/SignatureVerifier_Java
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 ?
@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)
OK, I had tried it yesterday with no success. I retry today.
@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].
OK, this is a simple messaging problem. Fixed on the tool, I will sent a Pull request soon.
@RemiBauzac oh yes, I improved the error message. Thank you!
@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
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..
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)
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)
Ah, it looks like this has something to do with DER ASN-1 encoding.
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.
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
Client-side
Crypto++
lib usessecp521r1
which is size132
: https://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Message_VerificationServer-side Go code generates size
139
: https://github.com/readium/readium-lcp-server/blob/feature/shiny-frontend/sign/sign.go#L55