mirror of
https://github.com/libp2p/go-openssl.git
synced 2025-01-28 05:00:08 +08:00
allow pKey to support any key type supported by OpenSSL.
This commit is contained in:
parent
4ea35d79e3
commit
1647be123d
158
key.go
158
key.go
@ -32,6 +32,26 @@ var (
|
|||||||
SHA512_Method Method = C.X_EVP_sha512()
|
SHA512_Method Method = C.X_EVP_sha512()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type KeyType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
KeyTypeNone KeyType = C.EVP_PKEY_NONE
|
||||||
|
KeyTypeRSA KeyType = C.EVP_PKEY_RSA
|
||||||
|
KeyTypeRSA2 KeyType = C.EVP_PKEY_RSA2
|
||||||
|
KeyTypeDSA KeyType = C.EVP_PKEY_DSA
|
||||||
|
KeyTypeDSA1 KeyType = C.EVP_PKEY_DSA1
|
||||||
|
KeyTypeDSA2 KeyType = C.EVP_PKEY_DSA2
|
||||||
|
KeyTypeDSA3 KeyType = C.EVP_PKEY_DSA3
|
||||||
|
KeyTypeDSA4 KeyType = C.EVP_PKEY_DSA4
|
||||||
|
KeyTypeDH KeyType = C.EVP_PKEY_DH
|
||||||
|
KeyTypeDHX KeyType = C.EVP_PKEY_DHX
|
||||||
|
KeyTypeEC KeyType = C.EVP_PKEY_EC
|
||||||
|
KeyTypeHMAC KeyType = C.EVP_PKEY_HMAC
|
||||||
|
KeyTypeCMAC KeyType = C.EVP_PKEY_CMAC
|
||||||
|
KeyTypeTLS1PRF KeyType = C.EVP_PKEY_TLS1_PRF
|
||||||
|
KeyTypeHKDF KeyType = C.EVP_PKEY_HKDF
|
||||||
|
)
|
||||||
|
|
||||||
type PublicKey interface {
|
type PublicKey interface {
|
||||||
// Verifies the data signature using PKCS1.15
|
// Verifies the data signature using PKCS1.15
|
||||||
VerifyPKCS1v15(method Method, data, sig []byte) error
|
VerifyPKCS1v15(method Method, data, sig []byte) error
|
||||||
@ -44,6 +64,19 @@ type PublicKey interface {
|
|||||||
// format
|
// format
|
||||||
MarshalPKIXPublicKeyDER() (der_block []byte, err error)
|
MarshalPKIXPublicKeyDER() (der_block []byte, err error)
|
||||||
|
|
||||||
|
// Type returns an identifier for what kind of key is represented by this
|
||||||
|
// object.
|
||||||
|
Type() KeyType
|
||||||
|
|
||||||
|
// BaseType returns an identifier for what kind of key is represented
|
||||||
|
// by this object.
|
||||||
|
// Keys that share same algorithm but use different legacy formats
|
||||||
|
// will have the same BaseType.
|
||||||
|
//
|
||||||
|
// For example, a key with a `Type() == KeyTypeRSA` and a key with a
|
||||||
|
// `Type() == KeyTypeRSA2` would both have `BaseType() == KeyTypeRSA`.
|
||||||
|
BaseType() KeyType
|
||||||
|
|
||||||
evpPKey() *C.EVP_PKEY
|
evpPKey() *C.EVP_PKEY
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +101,14 @@ type pKey struct {
|
|||||||
|
|
||||||
func (key *pKey) evpPKey() *C.EVP_PKEY { return key.key }
|
func (key *pKey) evpPKey() *C.EVP_PKEY { return key.key }
|
||||||
|
|
||||||
|
func (key *pKey) Type() KeyType {
|
||||||
|
return KeyType(C.EVP_PKEY_id(key.key))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (key *pKey) BaseType() KeyType {
|
||||||
|
return KeyType(C.EVP_PKEY_base_id(key.key))
|
||||||
|
}
|
||||||
|
|
||||||
func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) {
|
func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) {
|
||||||
ctx := C.X_EVP_MD_CTX_new()
|
ctx := C.X_EVP_MD_CTX_new()
|
||||||
defer C.X_EVP_MD_CTX_free(ctx)
|
defer C.X_EVP_MD_CTX_free(ctx)
|
||||||
@ -117,15 +158,15 @@ func (key *pKey) MarshalPKCS1PrivateKeyPEM() (pem_block []byte,
|
|||||||
return nil, errors.New("failed to allocate memory BIO")
|
return nil, errors.New("failed to allocate memory BIO")
|
||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
|
||||||
if rsa == nil {
|
// PEM_write_bio_PrivateKey_traditional will use the key-specific PKCS1
|
||||||
return nil, errors.New("failed getting rsa key")
|
// format if one is available for that key type, otherwise it will encode
|
||||||
}
|
// to a PKCS8 key.
|
||||||
defer C.RSA_free(rsa)
|
if int(C.PEM_write_bio_PrivateKey_traditional(bio, key.key, nil, nil,
|
||||||
if int(C.PEM_write_bio_RSAPrivateKey(bio, rsa, nil, nil, C.int(0), nil,
|
C.int(0), nil, nil)) != 1 {
|
||||||
nil)) != 1 {
|
|
||||||
return nil, errors.New("failed dumping private key")
|
return nil, errors.New("failed dumping private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.ReadAll(asAnyBio(bio))
|
return ioutil.ReadAll(asAnyBio(bio))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,14 +177,11 @@ func (key *pKey) MarshalPKCS1PrivateKeyDER() (der_block []byte,
|
|||||||
return nil, errors.New("failed to allocate memory BIO")
|
return nil, errors.New("failed to allocate memory BIO")
|
||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
|
||||||
if rsa == nil {
|
if int(C.i2d_PrivateKey_bio(bio, key.key)) != 1 {
|
||||||
return nil, errors.New("failed getting rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsa)
|
|
||||||
if int(C.i2d_RSAPrivateKey_bio(bio, rsa)) != 1 {
|
|
||||||
return nil, errors.New("failed dumping private key der")
|
return nil, errors.New("failed dumping private key der")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.ReadAll(asAnyBio(bio))
|
return ioutil.ReadAll(asAnyBio(bio))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,14 +192,12 @@ func (key *pKey) MarshalPKIXPublicKeyPEM() (pem_block []byte,
|
|||||||
return nil, errors.New("failed to allocate memory BIO")
|
return nil, errors.New("failed to allocate memory BIO")
|
||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
|
||||||
if rsa == nil {
|
rc := C.PEM_write_bio_PUBKEY(bio, key.key)
|
||||||
return nil, errors.New("failed getting rsa key")
|
if rc != 1 {
|
||||||
}
|
|
||||||
defer C.RSA_free(rsa)
|
|
||||||
if int(C.PEM_write_bio_RSA_PUBKEY(bio, rsa)) != 1 {
|
|
||||||
return nil, errors.New("failed dumping public key pem")
|
return nil, errors.New("failed dumping public key pem")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.ReadAll(asAnyBio(bio))
|
return ioutil.ReadAll(asAnyBio(bio))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,14 +208,11 @@ func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte,
|
|||||||
return nil, errors.New("failed to allocate memory BIO")
|
return nil, errors.New("failed to allocate memory BIO")
|
||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
|
||||||
if rsa == nil {
|
if int(C.i2d_PUBKEY_bio(bio, key.key)) != 1 {
|
||||||
return nil, errors.New("failed getting rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsa)
|
|
||||||
if int(C.i2d_RSA_PUBKEY_bio(bio, rsa)) != 1 {
|
|
||||||
return nil, errors.New("failed dumping public key der")
|
return nil, errors.New("failed dumping public key der")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.ReadAll(asAnyBio(bio))
|
return ioutil.ReadAll(asAnyBio(bio))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,20 +228,9 @@ func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) {
|
|||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
|
|
||||||
rsakey := C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, nil)
|
key := C.PEM_read_bio_PrivateKey(bio, nil, nil, nil)
|
||||||
if rsakey == nil {
|
|
||||||
return nil, errors.New("failed reading rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsakey)
|
|
||||||
|
|
||||||
// convert to PKEY
|
|
||||||
key := C.X_EVP_PKEY_new()
|
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
return nil, errors.New("failed reading private key")
|
||||||
}
|
|
||||||
if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 {
|
|
||||||
C.X_EVP_PKEY_free(key)
|
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pKey{key: key}
|
p := &pKey{key: key}
|
||||||
@ -232,20 +254,9 @@ func LoadPrivateKeyFromPEMWithPassword(pem_block []byte, password string) (
|
|||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
cs := C.CString(password)
|
cs := C.CString(password)
|
||||||
defer C.free(unsafe.Pointer(cs))
|
defer C.free(unsafe.Pointer(cs))
|
||||||
rsakey := C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, unsafe.Pointer(cs))
|
key := C.PEM_read_bio_PrivateKey(bio, nil, nil, unsafe.Pointer(cs))
|
||||||
if rsakey == nil {
|
|
||||||
return nil, errors.New("failed reading rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsakey)
|
|
||||||
|
|
||||||
// convert to PKEY
|
|
||||||
key := C.X_EVP_PKEY_new()
|
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
return nil, errors.New("failed reading private key")
|
||||||
}
|
|
||||||
if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 {
|
|
||||||
C.X_EVP_PKEY_free(key)
|
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pKey{key: key}
|
p := &pKey{key: key}
|
||||||
@ -267,20 +278,9 @@ func LoadPrivateKeyFromDER(der_block []byte) (PrivateKey, error) {
|
|||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
|
|
||||||
rsakey := C.d2i_RSAPrivateKey_bio(bio, nil)
|
key := C.d2i_PrivateKey_bio(bio, nil)
|
||||||
if rsakey == nil {
|
|
||||||
return nil, errors.New("failed reading rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsakey)
|
|
||||||
|
|
||||||
// convert to PKEY
|
|
||||||
key := C.X_EVP_PKEY_new()
|
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
return nil, errors.New("failed reading private key der")
|
||||||
}
|
|
||||||
if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 {
|
|
||||||
C.X_EVP_PKEY_free(key)
|
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pKey{key: key}
|
p := &pKey{key: key}
|
||||||
@ -309,20 +309,9 @@ func LoadPublicKeyFromPEM(pem_block []byte) (PublicKey, error) {
|
|||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
|
|
||||||
rsakey := C.PEM_read_bio_RSA_PUBKEY(bio, nil, nil, nil)
|
key := C.PEM_read_bio_PUBKEY(bio, nil, nil, nil)
|
||||||
if rsakey == nil {
|
|
||||||
return nil, errors.New("failed reading rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsakey)
|
|
||||||
|
|
||||||
// convert to PKEY
|
|
||||||
key := C.X_EVP_PKEY_new()
|
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
return nil, errors.New("failed reading public key der")
|
||||||
}
|
|
||||||
if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 {
|
|
||||||
C.X_EVP_PKEY_free(key)
|
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pKey{key: key}
|
p := &pKey{key: key}
|
||||||
@ -344,20 +333,9 @@ func LoadPublicKeyFromDER(der_block []byte) (PublicKey, error) {
|
|||||||
}
|
}
|
||||||
defer C.BIO_free(bio)
|
defer C.BIO_free(bio)
|
||||||
|
|
||||||
rsakey := C.d2i_RSA_PUBKEY_bio(bio, nil)
|
key := C.d2i_PUBKEY_bio(bio, nil)
|
||||||
if rsakey == nil {
|
|
||||||
return nil, errors.New("failed reading rsa key")
|
|
||||||
}
|
|
||||||
defer C.RSA_free(rsakey)
|
|
||||||
|
|
||||||
// convert to PKEY
|
|
||||||
key := C.X_EVP_PKEY_new()
|
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
return nil, errors.New("failed reading public key der")
|
||||||
}
|
|
||||||
if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 {
|
|
||||||
C.X_EVP_PKEY_free(key)
|
|
||||||
return nil, errors.New("failed converting to evp_pkey")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pKey{key: key}
|
p := &pKey{key: key}
|
||||||
|
Loading…
Reference in New Issue
Block a user