From b6c1d7802791b53a3a5736f1e97f786f3c5d49af Mon Sep 17 00:00:00 2001 From: Maksim Horbul Date: Thu, 9 Feb 2017 10:40:27 -0800 Subject: [PATCH 1/5] Add method to retrieve private key Modulus --- key.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/key.go b/key.go index cc17f5fc..ea29109f 100644 --- a/key.go +++ b/key.go @@ -19,6 +19,8 @@ package openssl // #include // #include // #include +// #include +// #include // // int EVP_SignInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { // return EVP_SignInit(ctx, type); @@ -86,6 +88,9 @@ type PrivateKey interface { // MarshalPKCS1PrivateKeyDER converts the private key to DER-encoded PKCS1 // format MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) + + // GetModulus returns private key modulus + GetModulus() (modulus []byte, err error) } type pKey struct { @@ -193,6 +198,20 @@ func (key *pKey) MarshalPKIXPublicKeyPEM() (pem_block []byte, return ioutil.ReadAll(asAnyBio(bio)) } +func (key *pKey) GetModulus() ([]byte, error) { + rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) + if rsa == nil { + return nil, errors.New("failed getting rsa key") + } + defer C.RSA_free(rsa) + + m := C.BN_bn2hex(rsa.n) + if m == nil { + return nil, errors.New("failed to find RSA key modulus") + } + return ([]byte)(C.GoString(m)), nil +} + func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) From 617fad0e2771df7f19fc51bdefd3b5b26bc7af68 Mon Sep 17 00:00:00 2001 From: Maksim Horbul Date: Thu, 9 Feb 2017 10:40:56 -0800 Subject: [PATCH 2/5] add method to load private key from ENGINE --- key.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/key.go b/key.go index ea29109f..fde6d13a 100644 --- a/key.go +++ b/key.go @@ -230,6 +230,19 @@ func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte, return ioutil.ReadAll(asAnyBio(bio)) } +func LoadPrivateKeyFromEngine(e *Engine, key_id []byte) (PrivateKey, error) { + key := C.ENGINE_load_private_key(e.e, (*C.char)(unsafe.Pointer(&key_id[0])), nil, nil) + if key == nil { + return nil, errors.New("Could not load private key from engine") + } + + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.EVP_PKEY_free(p.key) + }) + return p, nil +} + // LoadPrivateKeyFromPEM loads a private key from a PEM-encoded block. func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) { if len(pem_block) == 0 { From 54b69b46a2e366931ffe5a396b08e6f020751cb3 Mon Sep 17 00:00:00 2001 From: Maksim Horbul Date: Thu, 9 Feb 2017 12:21:03 -0800 Subject: [PATCH 3/5] free up memory as recommended in the docs --- key.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/key.go b/key.go index fde6d13a..e9e08481 100644 --- a/key.go +++ b/key.go @@ -21,6 +21,7 @@ package openssl // #include // #include // #include +// #include // // int EVP_SignInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { // return EVP_SignInit(ctx, type); @@ -209,6 +210,8 @@ func (key *pKey) GetModulus() ([]byte, error) { if m == nil { return nil, errors.New("failed to find RSA key modulus") } + defer C.CRYPTO_free(unsafe.Pointer(m)) + return ([]byte)(C.GoString(m)), nil } From cdc54bdc96c1a311611121e3380c6cb17540c057 Mon Sep 17 00:00:00 2001 From: Maksim Horbul Date: Mon, 13 Feb 2017 15:00:58 -0800 Subject: [PATCH 4/5] add tests for the GetModulus method --- key_test.go | 16 ++++++++++++++++ ssl_test.go | 2 ++ 2 files changed, 18 insertions(+) diff --git a/key_test.go b/key_test.go index 0af90128..6d5c383f 100644 --- a/key_test.go +++ b/key_test.go @@ -174,3 +174,19 @@ func TestSign(t *testing.T) { t.Fatal(err) } } + +func TestModulus(t *testing.T) { + key, err := LoadPrivateKeyFromPEM(keyBytes) + if err != nil { + t.Fatal(err) + } + modulus, err := key.GetModulus() + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(modulus, keyModulus) { + ioutil.WriteFile("calculated", []byte(hex.Dump(modulus)), 0644) + ioutil.WriteFile("hardcoded", []byte(hex.Dump(keyModulus)), 0644) + t.Fatal("invalid private key modulus bytes") + } +} diff --git a/ssl_test.go b/ssl_test.go index f83225de..4754916e 100644 --- a/ssl_test.go +++ b/ssl_test.go @@ -81,6 +81,8 @@ ucCCa4lOGgPtXJ0Qf1c8yq5vh4yqkQjrgUTkr+CFDGR6y4CxmNDQxEMYIajaIiSY qmgvgyRayemfO2zR0CPgC6wSoGBth+xW6g+WA8y0z76ZSaWpFi8lVM4= -----END RSA PRIVATE KEY----- `) + + keyModulus = []byte(`DD7F789C36F16CAE5AE734B8BC4A872C72A9526C5ABEA44BE685C4A8AA00CBA9E6E7AAEF0B77BDC7249EF83065C48115FCC594F91629CE30BDF5091EADF44FE3DDDA95EA9F867DD9452DEDC8AAD0B4FDB3D59C20C18AB072801238B82ACCABED55840C4F59C96B0E8EE5F504586EC1311FD95F9FE472BF178D31988E0126ACBD564D9DC63C13DBAC04645D1F5EC47C32FF4CFC17A9638BCB148DE68E78193CED8E3CBDC3D08640FEE3702B9E298C902500AD1269F073A3FFABAFC43EFE51E9DAC1917EA5A003ED982500907AB1916389AD1ABFBFB3F0CD16217D8F99A551C673B5849039CBCD1894CA9AF50BDA31BCB292D747AD64423011D2B23A44A0D9F74F`) ) func NetPipe(t testing.TB) (net.Conn, net.Conn) { From dabc732e87d6eb16f7962ed78dfff3cbab034c8e Mon Sep 17 00:00:00 2001 From: Maksim Horbul Date: Mon, 13 Feb 2017 15:03:56 -0800 Subject: [PATCH 5/5] add a short description to the method --- key.go | 1 + 1 file changed, 1 insertion(+) diff --git a/key.go b/key.go index e9e08481..8fcc2e90 100644 --- a/key.go +++ b/key.go @@ -233,6 +233,7 @@ func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte, return ioutil.ReadAll(asAnyBio(bio)) } +// LoadPrivateKeyFromEngine loads a provate key from an OpenSSL ENGINE func LoadPrivateKeyFromEngine(e *Engine, key_id []byte) (PrivateKey, error) { key := C.ENGINE_load_private_key(e.e, (*C.char)(unsafe.Pointer(&key_id[0])), nil, nil) if key == nil {