-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Secure key storage #481
Secure key storage #481
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,10 @@ func GenerateKey() ([]byte, []byte, error) { | |
} | ||
|
||
// convert to bytes | ||
skPem := PrivateKeyToPem(sk) | ||
skPem, err := PrivateKeyToPem(sk) | ||
if err != nil { | ||
return nil, nil, errors.Wrap(err, "Failed to encode private key to pem") | ||
} | ||
pkPem, err := GetPublicKeyPem(sk) | ||
if err != nil { | ||
return nil, nil, errors.Wrap(err, "Failed to marshal public key") | ||
|
@@ -49,39 +52,32 @@ func Encrypt(pk *rsa.PublicKey, plainText []byte) ([]byte, error) { | |
// PemToPrivateKey return rsa private key from pem | ||
func PemToPrivateKey(skPem []byte) (*rsa.PrivateKey, error) { | ||
block, _ := pem.Decode(skPem) | ||
// nolint | ||
enc := x509.IsEncryptedPEMBlock(block) | ||
b := block.Bytes | ||
if enc { | ||
var err error | ||
// nolint | ||
b, err = x509.DecryptPEMBlock(block, nil) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "Failed to decrypt private key") | ||
} | ||
if block == nil { | ||
return nil, errors.New("failed to decode PEM") | ||
} | ||
parsedSk, err := x509.ParsePKCS1PrivateKey(b) | ||
|
||
// Parse key as PKCS8 | ||
parsedSk, err := x509.ParsePKCS8PrivateKey(block.Bytes) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "Failed to parse private key") | ||
} | ||
return parsedSk, nil | ||
|
||
// Type assert to *rsa.PrivateKey | ||
ret, ok := parsedSk.(*rsa.PrivateKey) | ||
if !ok { | ||
return nil, errors.New("Failed to parse private key") | ||
} | ||
|
||
return ret, nil | ||
} | ||
|
||
// PemToPublicKey return rsa public key from pem | ||
func PemToPublicKey(pkPem []byte) (*rsa.PublicKey, error) { | ||
block, _ := pem.Decode(pkPem) | ||
// nolint | ||
enc := x509.IsEncryptedPEMBlock(block) | ||
b := block.Bytes | ||
if enc { | ||
var err error | ||
// nolint | ||
b, err = x509.DecryptPEMBlock(block, nil) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "Failed to decrypt private key") | ||
} | ||
if block == nil { | ||
return nil, errors.New("failed to decode PEM") | ||
} | ||
parsedPk, err := x509.ParsePKIXPublicKey(b) | ||
parsedPk, err := x509.ParsePKIXPublicKey(block.Bytes) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "Failed to parse public key") | ||
} | ||
|
@@ -92,13 +88,17 @@ func PemToPublicKey(pkPem []byte) (*rsa.PublicKey, error) { | |
} | ||
|
||
// PrivateKeyToPem converts privateKey to pem encoded | ||
func PrivateKeyToPem(sk *rsa.PrivateKey) []byte { | ||
func PrivateKeyToPem(sk *rsa.PrivateKey) ([]byte, error) { | ||
pemBytes, err := x509.MarshalPKCS8PrivateKey(sk) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see in SSV they use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From a discussion with Alan and as far as I understood, PKCS8 will just add a key-type tag. Follow this link for more So, it's more or less the same but it seems that PKCS8 is preferable if we can use it (the audit also suggests it). Therefore, it would be good if SSV also updates it. If not, I can restore to PKCS1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only thing is maybe node stores private keys and if we switch formats it may cause issues... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Btw, to be honest... this is an example of where we have too much implementation details in spec... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, I agree There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as commented above AFAIK, PKCS8 isn't backward compatible with PKCS1, so if we decide to go forward with this we'll need to do some migration in the node. The main issue is that private keys are created and stored outside of the node by operators. and they'll have to change the way their keys are encoded if we stop supporting PKCS1. |
||
if err != nil { | ||
return nil, err | ||
} | ||
return pem.EncodeToMemory( | ||
&pem.Block{ | ||
Type: "RSA PRIVATE KEY", | ||
Bytes: x509.MarshalPKCS1PrivateKey(sk), | ||
Bytes: pemBytes, | ||
}, | ||
) | ||
), nil | ||
} | ||
|
||
// GetPublicKeyPem get public key from private key and return []byte represent the public key | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK PKCS8 isn't backward compatible with PKCS1.. wouldn't this break stuff?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct
It depends on how these functions are being used. From your above comment, it seems that it would break indeed. So, I'll switch back to PKCS1