[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [tor-bugs] #26536 [Applications/Tor Browser]: Create APK signing keys
#26536: Create APK signing keys
-------------------------------------------------+-------------------------
Reporter: sysrqb | Owner: tbb-
| team
Type: task | Status:
| needs_information
Priority: Medium | Milestone:
Component: Applications/Tor Browser | Version:
Severity: Normal | Resolution:
Keywords: tbb-mobile, TBA-a3, tbb-8.5-must, | Actual Points:
TorBrowserTeam201904 |
Parent ID: | Points:
Reviewer: | Sponsor:
| Sponsor8
-------------------------------------------------+-------------------------
Changes (by sysrqb):
* cc: eighthave (added)
Comment:
This is a little-bit of a brain dump. I went on a deep-dive into the code
for APK signing and using a nitrokey as a key store. As far as I
understand it, the answer is "you can't because the stars didn't align
correctly" - but I'm CCing Hans in case I missed something. Maybe this
works if we get `opensc-pkcs11` packages from `stretch-backport`?
At the beginning, I followed some of the
[https://geoffreymetais.github.io/code/key-signing/ existing] guides for
putting a signing certificate in PKCS12 key store onto the nitrokey.
Unfortunately, that didn't work because importing the certificate via
`keytool` failed. When keytool "stored" the key, it gave key type as an
ASCII string instead of the binary number. This resulted in:
{{{
0x70d49bdbc700 19:54:34.511 [opensc-pkcs11] card-
openpgp.c:2827:pgp_store_key: Unknown key type 49.
0x70d49bdbc700 19:54:34.511 [opensc-pkcs11] card-
openpgp.c:2828:pgp_store_key: returning with: -1300 (Invalid arguments)
0x70d49bdbc700 19:54:34.511 [opensc-pkcs11] card-
openpgp.c:3009:pgp_card_ctl: returning with: -1300 (Invalid arguments)
0x70d49bdbc700 19:54:34.511 [opensc-pkcs11] card.c:961:sc_card_ctl:
returning with: -1300 (Invalid arguments)
0x70d49bdbc700 19:54:34.511 [opensc-pkcs11]
pkcs15-openpgp.c:142:openpgp_store_key: returning with: -1300 (Invalid
arguments)
0x70d49bdbc700 19:54:34.511 [opensc-pkcs11]
pkcs15-lib.c:1683:sc_pkcs15init_store_private_key: Card specific 'store
key' failed: -1300 (Invalid arguments)
}}}
Eventually, I found the documentation on the OpenSC
[https://github.com/OpenSC/OpenSC/wiki/OpenPGP-card#6-import-key-resp-
certificate wiki page], and I successfully imported the certificate and
key:
{{{
pkcs15-init --delete-objects privkey,pubkey,chain --id 3 --store-private-
key secret_and_certificate.p12 --format pkcs12 --auth-id 3 --verify-pin
}}}
And reading the stored public key and certificate information works
{{{
$ pkcs15-tool --read-public-key 3
Using reader with a card: Nitrokey Nitrokey Pro (000039610000000000000000)
00 00
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA8+4jHWnOQ18yStSqOYrv
MTGHaudFY0KLYfatjGXFIv3fbtzCT25hWtl4WY+MWVxjLy1R34Il7CZ0KvdHnYtF
7qN5rHwh6GZb37KsjwAIwLR6K6icqjnFgcCCfTVZnaPW4P1ARd1Ove7eOXkL5t1j
C2unkIvrOeIOqpxC28xbt7T3pD8OL53ZHgduLHzcwvj5tiZijzZoMeuRfS5U3vhZ
3wQghEYKrcsdU/+BFPjWZklJkrJgryt/TN2At3MylreeiDHLyLpUsCjPMgLf2oSF
VUBWfGKu2BPzK67hN84/wUmhCbCjbjL8sooqjS58L2fZsYn/0uU//47drenQXT4z
Vg5z7L8fjFggdycq57Xp0W4DdqCrOWBrIInnjLxKN9pNhfWWXbQgy213cXNIohtJ
NY8MNHQtp0tp9nRqKYjrgV4pEKf0kvUuFNzBdBS+c1WU5ratYr8KcB06PdJ0VwUB
AeVozzJTak5/0GmQi6zPIZe7nEwlhURt8r2iPE7dpnHPGogYA5WZUQcfjQOsjf84
qwCr+IyHzTeDgVAy+SiBaRlOrY6goopRjNjsCgzVxggA3haDoENrCaAmUkq+3/lO
DXrG7z4G+IZceAvBgYxkE0OJ/zDUMxBT6iWR1lgIIVxoeNH7Pk/nYnuSb7nBAxp3
j2/+h7v+NRQbNvJxsFB1518CAwEAAQ==
-----END PUBLIC KEY-----
$ keytool -providerClass sun.security.pkcs11.SunPKCS11 -providerArg
~/pkcs11_java.cfg -providerName SunPKCS11-OpenSC-PKCS11 -keystore NONE
-storetype PKCS11 -list
Enter keystore password:
Keystore type: PKCS11
Keystore provider: SunPKCS11-OpenSC-PKCS11
Your keystore contains 1 entry
Cardholder certificate, PrivateKeyEntry,
Certificate fingerprint (SHA-256):
EE:82:97:2E:1E:30:2F:67:9B:C7:0F:45:A4:EE:24:E0:80:80:05:BB:28:00:A1:E1:6F:68:3D:93:FC:79:C4:EF
}}}
However, signing with `apksigner` does not:
{{{
$ apksigner sign --provider-class sun.security.pkcs11.SunPKCS11
--provider-arg pkcs11_java.cfg --ks NONE --ks-type SunPKCS11-OpenSC-PKCS11
tor-browser-8.5a11-android-x86-multi-qa.apk
Exception in thread "main" java.lang.NoSuchMethodException:
sun.security.pkcs11.SunPKCS11.<init>(java.lang.String)
at java.base/java.lang.Class.getConstructor0(Class.java:3350)
at java.base/java.lang.Class.getConstructor(Class.java:2152)
at
com.android.apksigner.ApkSignerTool$ProviderInstallSpec.installProvider(ApkSignerTool.java:600)
at
com.android.apksigner.ApkSignerTool$ProviderInstallSpec.access$400(ApkSignerTool.java:575)
at
com.android.apksigner.ApkSignerTool.sign(ApkSignerTool.java:259)
at com.android.apksigner.ApkSignerTool.main(ApkSignerTool.java:89)
}}}
After digging into this, and tracing why `keytool` works but `apksigner`
does not, I found `apksigner` makes a bad assumption about how the
keystore is instantiated. In particular, when using a PKCS11 keystore,
`keytool`
[https://hg.openjdk.java.net/jdk/jdk/file/865ec913f916/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java#l274
instantiates the class] and then
[https://hg.openjdk.java.net/jdk/jdk/file/865ec913f916/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java#l277
configures it] (two steps process).
However, `apksigner` tries to do this in one step - by passing the
configuration
[https://android.googlesource.com/platform/tools/apksig/+/refs/heads/master/src/apksigner/java/com/android/apksigner/SignerParams.java#212
into the constructor]. This fails because the `SunPKCS11` class doesn't
define a one-parameter constructor, and this is why we get the
`java.lang.NoSuchMethodException`.
I tried finding an alternative method of configuring this, but I found
this is related to the version of Java I'm using. In
[https://hg.openjdk.java.net/jdk/jdk/file/a1ee9743f4ee/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java
Java 8], the exists a single-parameter String constructor in SunPKCS11,
but Java 11 does not have one. Unfortunately, I switched from Java 8 (in
Debian Stretch) to Java 11 (in Fedora 29) because there was a bug in
`opensc-pkcs11` that was patched in a newer version but it isn't available
in Stretch. (I lost the link to the bug, but I'll paste it later if I find
it).
Currently, when I try signing using Java 8, I get this - and I'm stuck:
{{{
$ OPENSC_DEBUG=9 ./android-sdk-linux/build-tools/28.0.2/apksigner sign
--verbose --provider-class sun.security.pkcs11.SunPKCS11 --provider-arg
pkcs11_java.cfg --ks NONE --ks-type PKCS11 tor-browser-8.5a11-android-x86
-multi-qa.apk
[snip]
0x7771e08c9700 17:05:15.124 [opensc-pkcs11] slot.c:328:card_detect:
Nitrokey Nitrokey Pro (000039610000000000000000) 00 00: Detection ended
0x7771e08c9700 17:05:15.124 [opensc-pkcs11] slot.c:357:card_detect_all:
All cards detected
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-global.c:503:C_GetSlotInfo: C_GetSlotInfo() get slot rv 0
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-global.c:530:C_GetSlotInfo: C_GetSlotInfo() flags 0x7
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-global.c:531:C_GetSlotInfo: C_GetSlotInfo(0x0) = CKR_OK
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-session.c:191:C_GetSessionInfo:
C_GetSessionInfo(hSession:0x7771d8255e30)
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-session.c:199:C_GetSessionInfo: C_GetSessionInfo(slot:0x0)
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-session.c:216:C_GetSessionInfo: C_GetSessionInfo(0x7771d8255e30) =
CKR_OK
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-object.c:336:C_FindObjectsInit: C_FindObjectsInit(slot = 0)
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-object.c:337:C_FindObjectsInit: C_FindObjectsInit(): CKA_TOKEN =
TRUE
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-object.c:337:C_FindObjectsInit: C_FindObjectsInit(): CKA_CLASS =
CKO_PRIVATE_KEY
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
misc.c:254:session_start_operation: called
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
misc.c:255:session_start_operation: Session 0x7771d8255e30, type 0
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
pkcs11-object.c:406:C_FindObjectsInit: 0 matching objects
0x7771e08c9700 17:05:15.124 [opensc-pkcs11]
misc.c:276:session_get_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:276:session_get_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:59:sc_find_release: freeing 0 handles used 0 at (nil)
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:336:C_FindObjectsInit: C_FindObjectsInit(slot = 0)
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:337:C_FindObjectsInit: C_FindObjectsInit(): CKA_TOKEN =
TRUE
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:337:C_FindObjectsInit: C_FindObjectsInit(): CKA_CLASS =
CKO_CERTIFICATE
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:254:session_start_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:255:session_start_operation: Session 0x7771d8255e30, type 0
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:406:C_FindObjectsInit: 0 matching objects
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:276:session_get_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:276:session_get_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:59:sc_find_release: freeing 0 handles used 0 at (nil)
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:336:C_FindObjectsInit: C_FindObjectsInit(slot = 0)
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:337:C_FindObjectsInit: C_FindObjectsInit(): CKA_TOKEN =
TRUE
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:337:C_FindObjectsInit: C_FindObjectsInit(): CKA_CLASS =
CKO_SECRET_KEY
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:254:session_start_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:255:session_start_operation: Session 0x7771d8255e30, type 0
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:406:C_FindObjectsInit: 0 matching objects
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:276:session_get_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
misc.c:276:session_get_operation: called
0x7771e08c9700 17:05:15.125 [opensc-pkcs11]
pkcs11-object.c:59:sc_find_release: freeing 0 handles used 0 at (nil)
Failed to load signer "signer #1": NONE does not contain key entries
}}}
While, `pkcs15-tool --dump` shows:
{{{
$ pkcs15-tool --dump
Using reader with a card: Nitrokey Nitrokey Pro (000039610000000000000000)
00 00
PKCS#15 Card [OpenPGP card]:
Version : 0
Serial number : 000500003961
Manufacturer ID: ZeitControl
Language : de
Flags : PRN generation, EID compliant
[...]
Private RSA Key [Authentication key]
Object Flags : [0x3], private, modifiable
Usage : [0x222], decrypt, unwrap, nonRepudiation
Access Flags : [0x1D], sensitive, alwaysSensitive, neverExtract,
local
ModLength : 4096
Key ref : 2 (0x2)
Native : yes
Auth ID : 02
ID : 03
MD:guid : 7300fc9e-b71d-2853-11d7-e05d5d9a91e4
Public RSA Key [Authentication key]
Object Flags : [0x2], modifiable
Usage : [0x51], encrypt, wrap, verify
Access Flags : [0x2], extract
ModLength : 4096
Key ref : 0 (0x0)
Native : no
Path : a401
ID : 03
X.509 Certificate [Cardholder certificate]
Object Flags : [0x0]
Authority : no
Path : 3f007f21
ID : 03
Encoded serial : 02 09 00CC76B8E0E29658BE
}}}
For the record:
{{{
$ cat pkcs11_java.cfg
name = OpenSC-PKCS11
description = SunPKCS11 via OpenSC
library = /usr/lib64/opensc-pkcs11.so
slotListIndex = 0
}}}
--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/26536#comment:14>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online
_______________________________________________
tor-bugs mailing list
tor-bugs@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-bugs