github.com/storacha/go-ucanto@v0.7.2/principal/rsa/verifier/verifier.go (about)

     1  package verifier
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/rsa"
     6  	"crypto/sha256"
     7  	"crypto/x509"
     8  	"fmt"
     9  
    10  	"github.com/storacha/go-ucanto/did"
    11  	"github.com/storacha/go-ucanto/principal"
    12  	"github.com/storacha/go-ucanto/principal/multiformat"
    13  	"github.com/storacha/go-ucanto/ucan/crypto/signature"
    14  )
    15  
    16  const Code = 0x1205
    17  const Name = "RSA"
    18  
    19  const SignatureCode = signature.RS256
    20  const SignatureAlgorithm = "RS256"
    21  
    22  func Parse(str string) (principal.Verifier, error) {
    23  	did, err := did.Parse(str)
    24  	if err != nil {
    25  		return nil, fmt.Errorf("parsing DID: %w", err)
    26  	}
    27  	return Decode(did.Bytes())
    28  }
    29  
    30  func Decode(b []byte) (principal.Verifier, error) {
    31  	utb, err := multiformat.UntagWith(Code, b, 0)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	pub, err := x509.ParsePKCS1PublicKey(utb)
    37  	if err != nil {
    38  		return nil, fmt.Errorf("parsing public key: %w", err)
    39  	}
    40  
    41  	return RSAVerifier{bytes: b, pubKey: pub}, nil
    42  }
    43  
    44  // FromRaw takes raw RSA public key in PKCS #1, ASN.1 DER form and tags with the
    45  // RSA verifier multiformat code, returning an RSA verifier.
    46  func FromRaw(b []byte) (principal.Verifier, error) {
    47  	tb := multiformat.TagWith(Code, b)
    48  	pub, err := x509.ParsePKCS1PublicKey(b)
    49  	if err != nil {
    50  		return nil, fmt.Errorf("parsing public key: %w", err)
    51  	}
    52  	return RSAVerifier{tb, pub}, nil
    53  }
    54  
    55  type RSAVerifier struct {
    56  	bytes  []byte
    57  	pubKey *rsa.PublicKey
    58  }
    59  
    60  func (v RSAVerifier) Code() uint64 {
    61  	return Code
    62  }
    63  
    64  func (v RSAVerifier) Verify(msg []byte, sig signature.Signature) bool {
    65  	if sig.Code() != signature.RS256 {
    66  		return false
    67  	}
    68  
    69  	hash := sha256.New()
    70  	hash.Write(msg)
    71  	digest := hash.Sum(nil)
    72  
    73  	err := rsa.VerifyPKCS1v15(v.pubKey, crypto.SHA256, digest, sig.Raw())
    74  	return err == nil
    75  }
    76  
    77  func (v RSAVerifier) DID() did.DID {
    78  	id, _ := did.Decode(v.bytes)
    79  	return id
    80  }
    81  
    82  func (v RSAVerifier) Encode() []byte {
    83  	return v.bytes
    84  }
    85  
    86  func (v RSAVerifier) Raw() []byte {
    87  	b, _ := multiformat.UntagWith(Code, v.bytes, 0)
    88  	return b
    89  }