rsa.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package keys
  2. import (
  3. "crypto"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/sha256"
  7. "crypto/x509"
  8. "encoding/json"
  9. "encoding/pem"
  10. "errors"
  11. "github.com/DataDog/go-tuf/data"
  12. )
  13. func init() {
  14. VerifierMap.Store(data.KeyTypeRSASSA_PSS_SHA256, NewRsaVerifier)
  15. SignerMap.Store(data.KeyTypeRSASSA_PSS_SHA256, NewRsaSigner)
  16. }
  17. func NewRsaVerifier() Verifier {
  18. return &rsaVerifier{}
  19. }
  20. func NewRsaSigner() Signer {
  21. return &rsaSigner{}
  22. }
  23. type rsaVerifier struct {
  24. PublicKey string `json:"public"`
  25. rsaKey *rsa.PublicKey
  26. key *data.PublicKey
  27. }
  28. func (p *rsaVerifier) Public() string {
  29. // Unique public key identifier, use a uniform encodng
  30. r, err := x509.MarshalPKIXPublicKey(p.rsaKey)
  31. if err != nil {
  32. // This shouldn't happen with a valid rsa key, but fallback on the
  33. // JSON public key string
  34. return string(p.PublicKey)
  35. }
  36. return string(r)
  37. }
  38. func (p *rsaVerifier) Verify(msg, sigBytes []byte) error {
  39. hash := sha256.Sum256(msg)
  40. return rsa.VerifyPSS(p.rsaKey, crypto.SHA256, hash[:], sigBytes, &rsa.PSSOptions{})
  41. }
  42. func (p *rsaVerifier) MarshalPublicKey() *data.PublicKey {
  43. return p.key
  44. }
  45. func (p *rsaVerifier) UnmarshalPublicKey(key *data.PublicKey) error {
  46. if err := json.Unmarshal(key.Value, p); err != nil {
  47. return err
  48. }
  49. var err error
  50. p.rsaKey, err = parseKey(p.PublicKey)
  51. if err != nil {
  52. return err
  53. }
  54. p.key = key
  55. return nil
  56. }
  57. // parseKey tries to parse a PEM []byte slice by attempting PKCS1 and PKIX in order.
  58. func parseKey(data string) (*rsa.PublicKey, error) {
  59. block, _ := pem.Decode([]byte(data))
  60. if block == nil {
  61. return nil, errors.New("tuf: pem decoding public key failed")
  62. }
  63. rsaPub, err := x509.ParsePKCS1PublicKey(block.Bytes)
  64. if err == nil {
  65. return rsaPub, nil
  66. }
  67. key, err := x509.ParsePKIXPublicKey(block.Bytes)
  68. if err == nil {
  69. rsaPub, ok := key.(*rsa.PublicKey)
  70. if !ok {
  71. return nil, errors.New("tuf: invalid rsa key")
  72. }
  73. return rsaPub, nil
  74. }
  75. return nil, errors.New("tuf: error unmarshalling rsa key")
  76. }
  77. type rsaSigner struct {
  78. *rsa.PrivateKey
  79. }
  80. type rsaPublic struct {
  81. // PEM encoded public key.
  82. PublicKey string `json:"public"`
  83. }
  84. func (s *rsaSigner) PublicData() *data.PublicKey {
  85. pub, _ := x509.MarshalPKIXPublicKey(s.Public().(*rsa.PublicKey))
  86. pubBytes := pem.EncodeToMemory(&pem.Block{
  87. Type: "RSA PUBLIC KEY",
  88. Bytes: pub,
  89. })
  90. keyValBytes, _ := json.Marshal(rsaPublic{PublicKey: string(pubBytes)})
  91. return &data.PublicKey{
  92. Type: data.KeyTypeRSASSA_PSS_SHA256,
  93. Scheme: data.KeySchemeRSASSA_PSS_SHA256,
  94. Algorithms: data.HashAlgorithms,
  95. Value: keyValBytes,
  96. }
  97. }
  98. func (s *rsaSigner) SignMessage(message []byte) ([]byte, error) {
  99. hash := sha256.Sum256(message)
  100. return rsa.SignPSS(rand.Reader, s.PrivateKey, crypto.SHA256, hash[:], &rsa.PSSOptions{})
  101. }
  102. func (s *rsaSigner) ContainsID(id string) bool {
  103. return s.PublicData().ContainsID(id)
  104. }
  105. func (s *rsaSigner) MarshalPrivateKey() (*data.PrivateKey, error) {
  106. return nil, errors.New("not implemented for test")
  107. }
  108. func (s *rsaSigner) UnmarshalPrivateKey(key *data.PrivateKey) error {
  109. return errors.New("not implemented for test")
  110. }
  111. func GenerateRsaKey() (*rsaSigner, error) {
  112. privkey, err := rsa.GenerateKey(rand.Reader, 2048)
  113. if err != nil {
  114. return nil, err
  115. }
  116. return &rsaSigner{privkey}, nil
  117. }