package crypto
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"errors"
"io"
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
"github.com/libp2p/go-libp2p/core/internal/catch"
)
type RsaPrivateKey struct {
sk rsa .PrivateKey
}
type RsaPublicKey struct {
k rsa .PublicKey
cached []byte
}
func GenerateRSAKeyPair (bits int , src io .Reader ) (PrivKey , PubKey , error ) {
if bits < MinRsaKeyBits {
return nil , nil , ErrRsaKeyTooSmall
}
if bits > maxRsaKeyBits {
return nil , nil , ErrRsaKeyTooBig
}
priv , err := rsa .GenerateKey (src , bits )
if err != nil {
return nil , nil , err
}
pk := priv .PublicKey
return &RsaPrivateKey {sk : *priv }, &RsaPublicKey {k : pk }, nil
}
func (pk *RsaPublicKey ) Verify (data , sig []byte ) (success bool , err error ) {
defer func () {
catch .HandlePanic (recover (), &err , "RSA signature verification" )
if err != nil {
success = false
}
}()
hashed := sha256 .Sum256 (data )
err = rsa .VerifyPKCS1v15 (&pk .k , crypto .SHA256 , hashed [:], sig )
if err != nil {
return false , err
}
return true , nil
}
func (pk *RsaPublicKey ) Type () pb .KeyType {
return pb .KeyType_RSA
}
func (pk *RsaPublicKey ) Raw () (res []byte , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "RSA public-key marshaling" ) }()
return x509 .MarshalPKIXPublicKey (&pk .k )
}
func (pk *RsaPublicKey ) Equals (k Key ) bool {
other , ok := (k ).(*RsaPublicKey )
if !ok {
return basicEquals (pk , k )
}
return pk .k .N .Cmp (other .k .N ) == 0 && pk .k .E == other .k .E
}
func (sk *RsaPrivateKey ) Sign (message []byte ) (sig []byte , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "RSA signing" ) }()
hashed := sha256 .Sum256 (message )
return rsa .SignPKCS1v15 (rand .Reader , &sk .sk , crypto .SHA256 , hashed [:])
}
func (sk *RsaPrivateKey ) GetPublic () PubKey {
return &RsaPublicKey {k : sk .sk .PublicKey }
}
func (sk *RsaPrivateKey ) Type () pb .KeyType {
return pb .KeyType_RSA
}
func (sk *RsaPrivateKey ) Raw () (res []byte , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "RSA private-key marshaling" ) }()
b := x509 .MarshalPKCS1PrivateKey (&sk .sk )
return b , nil
}
func (sk *RsaPrivateKey ) Equals (k Key ) bool {
other , ok := (k ).(*RsaPrivateKey )
if !ok {
return basicEquals (sk , k )
}
a := sk .sk
b := other .sk
return a .PublicKey .N .Cmp (b .PublicKey .N ) == 0 && a .PublicKey .E == b .PublicKey .E
}
func UnmarshalRsaPrivateKey (b []byte ) (key PrivKey , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "RSA private-key unmarshaling" ) }()
sk , err := x509 .ParsePKCS1PrivateKey (b )
if err != nil {
return nil , err
}
if sk .N .BitLen () < MinRsaKeyBits {
return nil , ErrRsaKeyTooSmall
}
if sk .N .BitLen () > maxRsaKeyBits {
return nil , ErrRsaKeyTooBig
}
return &RsaPrivateKey {sk : *sk }, nil
}
func UnmarshalRsaPublicKey (b []byte ) (key PubKey , err error ) {
defer func () { catch .HandlePanic (recover (), &err , "RSA public-key unmarshaling" ) }()
pub , err := x509 .ParsePKIXPublicKey (b )
if err != nil {
return nil , err
}
pk , ok := pub .(*rsa .PublicKey )
if !ok {
return nil , errors .New ("not actually an rsa public key" )
}
if pk .N .BitLen () < MinRsaKeyBits {
return nil , ErrRsaKeyTooSmall
}
if pk .N .BitLen () > maxRsaKeyBits {
return nil , ErrRsaKeyTooBig
}
return &RsaPublicKey {k : *pk }, nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .