github.com/kubri/kubri@v0.5.1-0.20240317001612-bda2aaef967e/pkg/crypto/rsa/rsa.go (about)

     1  package rsa
     2  
     3  import (
     4  	stdcrypto "crypto"
     5  	"crypto/rand"
     6  	"crypto/rsa"
     7  	"crypto/sha1"
     8  	"crypto/x509"
     9  	"encoding/pem"
    10  
    11  	"github.com/kubri/kubri/pkg/crypto"
    12  )
    13  
    14  type (
    15  	PrivateKey = rsa.PrivateKey
    16  	PublicKey  = rsa.PublicKey
    17  )
    18  
    19  // Sign signs the data with the private key.
    20  func Sign(key *PrivateKey, data []byte) ([]byte, error) {
    21  	if key == nil {
    22  		return nil, crypto.ErrInvalidKey
    23  	}
    24  	hashed := sha1.Sum(data)
    25  	return rsa.SignPKCS1v15(nil, key, stdcrypto.SHA1, hashed[:])
    26  }
    27  
    28  // Verify verifies the signature of the data with the public key.
    29  func Verify(key *PublicKey, data, sig []byte) bool {
    30  	if key == nil {
    31  		return false
    32  	}
    33  	hashed := sha1.Sum(data)
    34  	err := rsa.VerifyPKCS1v15(key, stdcrypto.SHA1, hashed[:], sig)
    35  	return err == nil
    36  }
    37  
    38  // NewPrivateKey returns a new private key.
    39  func NewPrivateKey() (*PrivateKey, error) {
    40  	return rsa.GenerateKey(rand.Reader, 2048)
    41  }
    42  
    43  // MarshalPrivateKey returns the PEM encoded private key.
    44  func MarshalPrivateKey(key *PrivateKey) ([]byte, error) {
    45  	if key == nil {
    46  		return nil, crypto.ErrInvalidKey
    47  	}
    48  	b, err := x509.MarshalPKCS8PrivateKey(key)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	return pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: b}), nil
    53  }
    54  
    55  // UnmarshalPrivateKey returns a private key from a PEM encoded key.
    56  func UnmarshalPrivateKey(b []byte) (*PrivateKey, error) {
    57  	block, _ := pem.Decode(b)
    58  	if block == nil {
    59  		return nil, crypto.ErrInvalidKey
    60  	}
    61  	key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
    62  	if err != nil {
    63  		return nil, crypto.ErrInvalidKey
    64  	}
    65  	rsaKey, ok := key.(*PrivateKey)
    66  	if !ok {
    67  		return nil, crypto.ErrWrongKeyType
    68  	}
    69  	return rsaKey, nil
    70  }
    71  
    72  // Public extracts the public key from a private key.
    73  func Public(key *PrivateKey) *PublicKey {
    74  	return key.Public().(*PublicKey) //nolint:forcetypeassert
    75  }
    76  
    77  // MarshalPublicKey returns the PEM encoded public key.
    78  func MarshalPublicKey(key *PublicKey) ([]byte, error) {
    79  	if key == nil {
    80  		return nil, crypto.ErrInvalidKey
    81  	}
    82  	b, err := x509.MarshalPKIXPublicKey(key)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	return pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: b}), nil
    87  }
    88  
    89  // UnmarshalPublicKey returns a public key from a PEM encoded key.
    90  func UnmarshalPublicKey(b []byte) (*PublicKey, error) {
    91  	block, _ := pem.Decode(b)
    92  	if block == nil {
    93  		return nil, crypto.ErrInvalidKey
    94  	}
    95  	key, err := x509.ParsePKIXPublicKey(block.Bytes)
    96  	if err != nil {
    97  		return nil, crypto.ErrInvalidKey
    98  	}
    99  	rsaKey, ok := key.(*PublicKey)
   100  	if !ok {
   101  		return nil, crypto.ErrWrongKeyType
   102  	}
   103  	return rsaKey, nil
   104  }