Skip to content

Commit

Permalink
feat: support PKCS8 keys for APK signing (#804)
Browse files Browse the repository at this point in the history
* support PKCS8 keys for APK signing

Call correct parsing function for given RSA key depending on its PEM
header. So we can use both PKCS1 and PKCS8 keys to sign APK files.

Fixes #799

* fix golangci-lint warnings
  • Loading branch information
cnt0 authored Mar 27, 2024
1 parent 04298ac commit 1667ef9
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 11 deletions.
28 changes: 25 additions & 3 deletions internal/sign/rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ var (
errNoRSAKey = errors.New("key is not an RSA key")
)

const (
PKCS1PrivkeyPreamble = "RSA PRIVATE KEY"
PKCS8PrivkeyPreamble = "PRIVATE KEY"
)

// RSASignSHA1Digest signs the provided SHA1 message digest. The key file
// must be in the PEM format and can either be encrypted or not.
func RSASignSHA1Digest(sha1Digest []byte, keyFile, passphrase string) ([]byte, error) {
Expand Down Expand Up @@ -53,9 +58,26 @@ func RSASignSHA1Digest(sha1Digest []byte, keyFile, passphrase string) ([]byte, e
blockData = decryptedBlockData
}

priv, err := x509.ParsePKCS1PrivateKey(blockData)
if err != nil {
return nil, fmt.Errorf("parse PKCS1 private key: %w", err)
var priv crypto.Signer

switch block.Type {
case PKCS1PrivkeyPreamble:
priv, err = x509.ParsePKCS1PrivateKey(blockData)
if err != nil {
return nil, fmt.Errorf("parse PKCS#1 private key: %w", err)
}
case PKCS8PrivkeyPreamble:
privAny, err := x509.ParsePKCS8PrivateKey(blockData)
if err != nil {
return nil, fmt.Errorf("parse PKCS#8 private key: %w", err)
}
privTmp, ok := privAny.(crypto.Signer)
if !ok {
return nil, fmt.Errorf("cannot sign with given private key")
}
priv = privTmp
default:
return nil, fmt.Errorf(`key type "%v" is not supported`, block.Type)
}

signature, err := priv.Sign(rand.Reader, sha1Digest, crypto.SHA1)
Expand Down
38 changes: 30 additions & 8 deletions internal/sign/rsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ func TestRSASignAndVerify(t *testing.T) {
pubKey string
passphrase string
}{
{"unprotected", "testdata/rsa_unprotected.priv", "testdata/rsa_unprotected.pub", ""},
{"protected", "testdata/rsa.priv", "testdata/rsa.pub", pass},
{"unprotected pkcs1", "testdata/rsa_unprotected.priv", "testdata/rsa_unprotected.pub", ""},
{"protected pkcs1", "testdata/rsa.priv", "testdata/rsa.pub", pass},
{"unprotected pkcs8", "testdata/rsa_pkcs8.priv", "testdata/rsa_pkcs8.pub", ""},
}

for _, testCase := range testCases {
Expand Down Expand Up @@ -54,18 +55,39 @@ func TestInvalidHash(t *testing.T) {
func TestRSAVerifyWrongKey(t *testing.T) {
digest := sha1.New().Sum(nil) // nolint:gosec

sig, err := rsaSign(bytes.NewReader(digest), "testdata/rsa_unprotected.priv", "")
require.NoError(t, err)
testCases := []struct {
name string
privKey string
pubKey string
}{
{"pkcs1", "testdata/rsa_unprotected.priv", "testdata/rsa_unprotected.pub"},
{"pkcs8", "testdata/rsa_pkcs8.priv", "testdata/rsa_pkcs8.pub"},
}

for _, testCase := range testCases {
sig, err := rsaSign(bytes.NewReader(digest), testCase.privKey, "")
require.NoError(t, err)

err = RSAVerifySHA1Digest(digest, sig, "testdata/rsa.pub")
require.EqualError(t, err, "verify PKCS1v15 signature: crypto/rsa: verification error")
err = RSAVerifySHA1Digest(digest, sig, testCase.pubKey)
require.EqualError(t, err, "verify PKCS1v15 signature: crypto/rsa: verification error")
}
}

func TestRSAVerifyWrongSignature(t *testing.T) {
digest := sha1.New().Sum(nil) // nolint:gosec

err := RSAVerifySHA1Digest(digest, []byte{}, "testdata/rsa.pub")
require.EqualError(t, err, "verify PKCS1v15 signature: crypto/rsa: verification error")
testCases := []struct {
name string
pubKey string
}{
{"pkcs1", "testdata/rsa.pub"},
{"pkcs8", "testdata/rsa_pkcs8.pub"},
}

for _, testCase := range testCases {
err := RSAVerifySHA1Digest(digest, []byte{}, testCase.pubKey)
require.EqualError(t, err, "verify PKCS1v15 signature: crypto/rsa: verification error")
}
}

func TestRSAVerifyWrongPublicKeyFormat(t *testing.T) {
Expand Down
28 changes: 28 additions & 0 deletions internal/sign/testdata/rsa_pkcs8.priv
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbfacH7+FQJmKF
2gadVTUGceI/Edjo0RDHG9Y9xLlA1VJ+HppgHGDYkek+kqLRSwcqKJ8g58M8hYRK
saOAa2OnMfgQ+B0qg191i7VwNrCm4YxgbP1t0z1QWUYX4G97hV+wS7MUFVz8+2H1
2I4aKw3iNoBINIKlDJgVgxvR4v85Ly4sEFT7PNl7xEE7sxIOiDMv/EL+M4HXrdx7
OCE4IcwyCyJFmBcSoc/qbTO87LDE/K4EBR0Lte/IJApid3u1gwfliOEeyCKVh1JH
AMNJ7s5RjpuW6XJMNMba+CyUTDiGmnbbxvEGvb6trJfDUHd2ChsD+3HR2qx4lNQA
epdUrQsdAgMBAAECggEAMvw3qhTTUlJwTWZtZeuukw4uP3dOWxqBWrcBJ70ESWak
MG68bnn5FyWhuCrIznQuuGDSQgsEI5FiPxWPhNutPN/TH2H7KG525K+s2GGj3EgF
WzrGDdZlZj4ulYpJazh6l1GmShKCVLOyODDzJWn94h/F4b/s3xkTVN/tPO6NWcNJ
MHUM8wYXtUP4jqfJvWljJPFrzKZBRVnB9PV+VtZRtX880VnMwQ76CjC8fLbaJQRT
XXDLl12FkULWQzJieQr8XJLhb8hLSytBovbqbO24NbMjGFx1hxHdwyziceDPtu04
4R11Zi/YK4DOYi7wrQfxuqyquHH0lAPK648b60HBMwKBgQD2mYzqCq11qHKjrKLV
AR3ufemcN40b7PjcxpXccaNzEzkBaWlRlqhdhO/naLXKHM97hNotji002/whANx5
0MYcjdo+VnYT/OYmxexVbsLjFsV0B9LOY1zrSyBAxxyjlSTdjBslOXMDtDnPKpZQ
ydjqFqlrpAZNXuOjBtaRVcC7pwKBgQDj24740wfDnuzbOKxcaTzBLf+Ak7aNI3xz
E8e9A2yOUBWhnpmi0fwiws5IE0ghqJBWrjdrwjna+B9Gs6HKMyTNatCYh8SdjxgQ
JivJ3jrKVrP8ixojz/cuNDXC6KJEHvklaLARMO6BPSaB88oR425Y0BZcw2XBNuU/
JS1YGCLLmwKBgCFWiPJrFyA88aKnCCx7xiwj4Z049V69HrfaMRBoXIyGIMLMGWzq
TUC3ZCeIxGrakkJEp6pY+kuXIfLkRupBC0d49fRPhA8XtZWwVE8Idlh1D6SsGhfE
3x8APRAE2x5SX3WEJ3dU2PO7PcWAIGozn5umDKl8t01mcqfrmL51NWUpAoGAVDtf
EAbbMOq4PpYlyYexyOwbLsnsSyKaJ+RhCzOP1tAuHvAFdZZQsfz3ytct7BtnOFPw
8un6/0KINVfEcH4VlcZt1GUkPuaeC6JAv8BiVVhV8v7tK93+T1tHoITlL2+PxM99
fu1qzeXwLUwVICXGLhjGm4Y0QIftmTlCGPXbLw8CgYBDiihffbawacxp79CZJUyd
DFvVvCLgwu1K9JRyykxyVPOZAcS/7x5IzRhpQdy51A5xG4WjBkNghGNosbnSaiFr
cCzEtKiNHefbSNUd5T3w8NO97y26BmtylyUrx+qIGr5XWHYFUFmgAmErqFVRLheT
4E9lCp7uSkx2AlbSgs+ugQ==
-----END PRIVATE KEY-----
9 changes: 9 additions & 0 deletions internal/sign/testdata/rsa_pkcs8.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA232nB+/hUCZihdoGnVU1
BnHiPxHY6NEQxxvWPcS5QNVSfh6aYBxg2JHpPpKi0UsHKiifIOfDPIWESrGjgGtj
pzH4EPgdKoNfdYu1cDawpuGMYGz9bdM9UFlGF+Bve4VfsEuzFBVc/Pth9diOGisN
4jaASDSCpQyYFYMb0eL/OS8uLBBU+zzZe8RBO7MSDogzL/xC/jOB163cezghOCHM
MgsiRZgXEqHP6m0zvOywxPyuBAUdC7XvyCQKYnd7tYMH5YjhHsgilYdSRwDDSe7O
UY6blulyTDTG2vgslEw4hpp228bxBr2+rayXw1B3dgobA/tx0dqseJTUAHqXVK0L
HQIDAQAB
-----END PUBLIC KEY-----

0 comments on commit 1667ef9

Please sign in to comment.