github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/verifiable/jws.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  SPDX-License-Identifier: Apache-2.0
     4  */
     5  
     6  package verifiable
     7  
     8  import (
     9  	"encoding/json"
    10  	"fmt"
    11  
    12  	"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
    13  	"github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
    14  )
    15  
    16  // Signer defines signer interface which is used to sign VC JWT.
    17  type Signer interface {
    18  	Sign(data []byte) ([]byte, error)
    19  	Alg() string
    20  }
    21  
    22  // JwtSigner implement jose.Signer interface.
    23  type JwtSigner struct {
    24  	signer  Signer
    25  	headers map[string]interface{}
    26  }
    27  
    28  // GetJWTSigner returns JWT Signer.
    29  func GetJWTSigner(signer Signer, algorithm string) *JwtSigner {
    30  	headers := map[string]interface{}{
    31  		jose.HeaderAlgorithm: algorithm,
    32  	}
    33  
    34  	return &JwtSigner{signer: signer, headers: headers}
    35  }
    36  
    37  // Sign returns signature.
    38  func (s JwtSigner) Sign(data []byte) ([]byte, error) {
    39  	return s.signer.Sign(data)
    40  }
    41  
    42  // Headers returns headers.
    43  func (s JwtSigner) Headers() jose.Headers {
    44  	return s.headers
    45  }
    46  
    47  // noVerifier is used when no JWT signature verification is needed.
    48  // To be used with precaution.
    49  type noVerifier struct{}
    50  
    51  func (v noVerifier) Verify(_ jose.Headers, _, _, _ []byte) error {
    52  	return nil
    53  }
    54  
    55  // MarshalJWS serializes JWT presentation claims into signed form (JWS).
    56  func marshalJWS(jwtClaims interface{}, signatureAlg JWSAlgorithm, signer Signer, keyID string) (string, error) {
    57  	algName, err := signatureAlg.Name()
    58  	if err != nil {
    59  		return "", err
    60  	}
    61  
    62  	headers := map[string]interface{}{
    63  		jose.HeaderKeyID: keyID,
    64  	}
    65  
    66  	token, err := jwt.NewSigned(jwtClaims, headers, GetJWTSigner(signer, algName))
    67  	if err != nil {
    68  		return "", err
    69  	}
    70  
    71  	return token.Serialize(false)
    72  }
    73  
    74  func unmarshalJWS(rawJwt string, checkProof bool, fetcher PublicKeyFetcher, claims interface{}) error {
    75  	var verifier jose.SignatureVerifier
    76  
    77  	if checkProof {
    78  		verifier = jwt.NewVerifier(jwt.KeyResolverFunc(fetcher))
    79  	} else {
    80  		verifier = &noVerifier{}
    81  	}
    82  
    83  	_, claimsRaw, err := jwt.Parse(rawJwt,
    84  		jwt.WithSignatureVerifier(verifier),
    85  		jwt.WithIgnoreClaimsMapDecoding(true),
    86  	)
    87  	if err != nil {
    88  		return fmt.Errorf("parse JWT: %w", err)
    89  	}
    90  
    91  	err = json.Unmarshal(claimsRaw, claims)
    92  	if err != nil {
    93  		return err
    94  	}
    95  
    96  	return nil
    97  }