mirror of
https://github.com/libp2p/go-openssl.git
synced 2025-01-15 02:40:09 +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()
|
||||
)
|
||||
|
||||
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 {
|
||||
// Verifies the data signature using PKCS1.15
|
||||
VerifyPKCS1v15(method Method, data, sig []byte) error
|
||||
@ -44,6 +64,19 @@ type PublicKey interface {
|
||||
// format
|
||||
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
|
||||
}
|
||||
|
||||
@ -68,6 +101,14 @@ type pKey struct {
|
||||
|
||||
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) {
|
||||
ctx := C.X_EVP_MD_CTX_new()
|
||||
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")
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
||||
if rsa == nil {
|
||||
return nil, errors.New("failed getting rsa key")
|
||||
}
|
||||
defer C.RSA_free(rsa)
|
||||
if int(C.PEM_write_bio_RSAPrivateKey(bio, rsa, nil, nil, C.int(0), nil,
|
||||
nil)) != 1 {
|
||||
|
||||
// PEM_write_bio_PrivateKey_traditional will use the key-specific PKCS1
|
||||
// format if one is available for that key type, otherwise it will encode
|
||||
// to a PKCS8 key.
|
||||
if int(C.PEM_write_bio_PrivateKey_traditional(bio, key.key, nil, nil,
|
||||
C.int(0), nil, nil)) != 1 {
|
||||
return nil, errors.New("failed dumping private key")
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
||||
if rsa == nil {
|
||||
return nil, errors.New("failed getting rsa key")
|
||||
}
|
||||
defer C.RSA_free(rsa)
|
||||
if int(C.i2d_RSAPrivateKey_bio(bio, rsa)) != 1 {
|
||||
|
||||
if int(C.i2d_PrivateKey_bio(bio, key.key)) != 1 {
|
||||
return nil, errors.New("failed dumping private key der")
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
||||
if rsa == nil {
|
||||
return nil, errors.New("failed getting rsa key")
|
||||
}
|
||||
defer C.RSA_free(rsa)
|
||||
if int(C.PEM_write_bio_RSA_PUBKEY(bio, rsa)) != 1 {
|
||||
|
||||
rc := C.PEM_write_bio_PUBKEY(bio, key.key)
|
||||
if rc != 1 {
|
||||
return nil, errors.New("failed dumping public key pem")
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key))
|
||||
if rsa == nil {
|
||||
return nil, errors.New("failed getting rsa key")
|
||||
}
|
||||
defer C.RSA_free(rsa)
|
||||
if int(C.i2d_RSA_PUBKEY_bio(bio, rsa)) != 1 {
|
||||
|
||||
if int(C.i2d_PUBKEY_bio(bio, key.key)) != 1 {
|
||||
return nil, errors.New("failed dumping public key der")
|
||||
}
|
||||
|
||||
return ioutil.ReadAll(asAnyBio(bio))
|
||||
}
|
||||
|
||||
@ -195,20 +228,9 @@ func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) {
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
|
||||
rsakey := C.PEM_read_bio_RSAPrivateKey(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()
|
||||
key := C.PEM_read_bio_PrivateKey(bio, nil, nil, nil)
|
||||
if key == nil {
|
||||
return nil, errors.New("failed converting to evp_pkey")
|
||||
}
|
||||
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")
|
||||
return nil, errors.New("failed reading private key")
|
||||
}
|
||||
|
||||
p := &pKey{key: key}
|
||||
@ -232,20 +254,9 @@ func LoadPrivateKeyFromPEMWithPassword(pem_block []byte, password string) (
|
||||
defer C.BIO_free(bio)
|
||||
cs := C.CString(password)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
rsakey := C.PEM_read_bio_RSAPrivateKey(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()
|
||||
key := C.PEM_read_bio_PrivateKey(bio, nil, nil, unsafe.Pointer(cs))
|
||||
if key == nil {
|
||||
return nil, errors.New("failed converting to evp_pkey")
|
||||
}
|
||||
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")
|
||||
return nil, errors.New("failed reading private key")
|
||||
}
|
||||
|
||||
p := &pKey{key: key}
|
||||
@ -267,20 +278,9 @@ func LoadPrivateKeyFromDER(der_block []byte) (PrivateKey, error) {
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
|
||||
rsakey := C.d2i_RSAPrivateKey_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()
|
||||
key := C.d2i_PrivateKey_bio(bio, nil)
|
||||
if key == nil {
|
||||
return nil, errors.New("failed converting to evp_pkey")
|
||||
}
|
||||
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")
|
||||
return nil, errors.New("failed reading private key der")
|
||||
}
|
||||
|
||||
p := &pKey{key: key}
|
||||
@ -309,20 +309,9 @@ func LoadPublicKeyFromPEM(pem_block []byte) (PublicKey, error) {
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
|
||||
rsakey := C.PEM_read_bio_RSA_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()
|
||||
key := C.PEM_read_bio_PUBKEY(bio, nil, nil, nil)
|
||||
if key == nil {
|
||||
return nil, errors.New("failed converting to evp_pkey")
|
||||
}
|
||||
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")
|
||||
return nil, errors.New("failed reading public key der")
|
||||
}
|
||||
|
||||
p := &pKey{key: key}
|
||||
@ -344,20 +333,9 @@ func LoadPublicKeyFromDER(der_block []byte) (PublicKey, error) {
|
||||
}
|
||||
defer C.BIO_free(bio)
|
||||
|
||||
rsakey := C.d2i_RSA_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()
|
||||
key := C.d2i_PUBKEY_bio(bio, nil)
|
||||
if key == nil {
|
||||
return nil, errors.New("failed converting to evp_pkey")
|
||||
}
|
||||
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")
|
||||
return nil, errors.New("failed reading public key der")
|
||||
}
|
||||
|
||||
p := &pKey{key: key}
|
||||
|
Loading…
Reference in New Issue
Block a user