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 }