github.com/lestrrat-go/jwx/v2@v2.0.21/internal/keyconv/keyconv.go (about)

     1  package keyconv
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/ecdsa"
     6  	"crypto/rsa"
     7  	"fmt"
     8  
     9  	"github.com/lestrrat-go/blackmagic"
    10  	"github.com/lestrrat-go/jwx/v2/jwk"
    11  	"golang.org/x/crypto/ed25519"
    12  )
    13  
    14  // RSAPrivateKey assigns src to dst.
    15  // `dst` should be a pointer to a rsa.PrivateKey.
    16  // `src` may be rsa.PrivateKey, *rsa.PrivateKey, or a jwk.Key
    17  func RSAPrivateKey(dst, src interface{}) error {
    18  	if jwkKey, ok := src.(jwk.Key); ok {
    19  		var raw rsa.PrivateKey
    20  		if err := jwkKey.Raw(&raw); err != nil {
    21  			return fmt.Errorf(`keyconv: failed to produce rsa.PrivateKey from %T: %w`, src, err)
    22  		}
    23  		src = &raw
    24  	}
    25  
    26  	var ptr *rsa.PrivateKey
    27  	switch src := src.(type) {
    28  	case rsa.PrivateKey:
    29  		ptr = &src
    30  	case *rsa.PrivateKey:
    31  		ptr = src
    32  	default:
    33  		return fmt.Errorf(`keyconv: expected rsa.PrivateKey or *rsa.PrivateKey, got %T`, src)
    34  	}
    35  
    36  	return blackmagic.AssignIfCompatible(dst, ptr)
    37  }
    38  
    39  // RSAPublicKey assigns src to dst
    40  // `dst` should be a pointer to a non-zero rsa.PublicKey.
    41  // `src` may be rsa.PublicKey, *rsa.PublicKey, or a jwk.Key
    42  func RSAPublicKey(dst, src interface{}) error {
    43  	if jwkKey, ok := src.(jwk.Key); ok {
    44  		pk, err := jwk.PublicRawKeyOf(jwkKey)
    45  		if err != nil {
    46  			return fmt.Errorf(`keyconv: failed to produce public key from %T: %w`, src, err)
    47  		}
    48  		src = pk
    49  	}
    50  
    51  	var ptr *rsa.PublicKey
    52  	switch src := src.(type) {
    53  	case rsa.PrivateKey:
    54  		ptr = &src.PublicKey
    55  	case *rsa.PrivateKey:
    56  		ptr = &src.PublicKey
    57  	case rsa.PublicKey:
    58  		ptr = &src
    59  	case *rsa.PublicKey:
    60  		ptr = src
    61  	default:
    62  		return fmt.Errorf(`keyconv: expected rsa.PublicKey/rsa.PrivateKey or *rsa.PublicKey/*rsa.PrivateKey, got %T`, src)
    63  	}
    64  
    65  	return blackmagic.AssignIfCompatible(dst, ptr)
    66  }
    67  
    68  // ECDSAPrivateKey assigns src to dst, converting its type from a
    69  // non-pointer to a pointer
    70  func ECDSAPrivateKey(dst, src interface{}) error {
    71  	if jwkKey, ok := src.(jwk.Key); ok {
    72  		var raw ecdsa.PrivateKey
    73  		if err := jwkKey.Raw(&raw); err != nil {
    74  			return fmt.Errorf(`keyconv: failed to produce ecdsa.PrivateKey from %T: %w`, src, err)
    75  		}
    76  		src = &raw
    77  	}
    78  
    79  	var ptr *ecdsa.PrivateKey
    80  	switch src := src.(type) {
    81  	case ecdsa.PrivateKey:
    82  		ptr = &src
    83  	case *ecdsa.PrivateKey:
    84  		ptr = src
    85  	default:
    86  		return fmt.Errorf(`keyconv: expected ecdsa.PrivateKey or *ecdsa.PrivateKey, got %T`, src)
    87  	}
    88  	return blackmagic.AssignIfCompatible(dst, ptr)
    89  }
    90  
    91  // ECDSAPublicKey assigns src to dst, converting its type from a
    92  // non-pointer to a pointer
    93  func ECDSAPublicKey(dst, src interface{}) error {
    94  	if jwkKey, ok := src.(jwk.Key); ok {
    95  		pk, err := jwk.PublicRawKeyOf(jwkKey)
    96  		if err != nil {
    97  			return fmt.Errorf(`keyconv: failed to produce public key from %T: %w`, src, err)
    98  		}
    99  		src = pk
   100  	}
   101  
   102  	var ptr *ecdsa.PublicKey
   103  	switch src := src.(type) {
   104  	case ecdsa.PrivateKey:
   105  		ptr = &src.PublicKey
   106  	case *ecdsa.PrivateKey:
   107  		ptr = &src.PublicKey
   108  	case ecdsa.PublicKey:
   109  		ptr = &src
   110  	case *ecdsa.PublicKey:
   111  		ptr = src
   112  	default:
   113  		return fmt.Errorf(`keyconv: expected ecdsa.PublicKey/ecdsa.PrivateKey or *ecdsa.PublicKey/*ecdsa.PrivateKey, got %T`, src)
   114  	}
   115  	return blackmagic.AssignIfCompatible(dst, ptr)
   116  }
   117  
   118  func ByteSliceKey(dst, src interface{}) error {
   119  	if jwkKey, ok := src.(jwk.Key); ok {
   120  		var raw []byte
   121  		if err := jwkKey.Raw(&raw); err != nil {
   122  			return fmt.Errorf(`keyconv: failed to produce []byte from %T: %w`, src, err)
   123  		}
   124  		src = raw
   125  	}
   126  
   127  	if _, ok := src.([]byte); !ok {
   128  		return fmt.Errorf(`keyconv: expected []byte, got %T`, src)
   129  	}
   130  	return blackmagic.AssignIfCompatible(dst, src)
   131  }
   132  
   133  func Ed25519PrivateKey(dst, src interface{}) error {
   134  	if jwkKey, ok := src.(jwk.Key); ok {
   135  		var raw ed25519.PrivateKey
   136  		if err := jwkKey.Raw(&raw); err != nil {
   137  			return fmt.Errorf(`failed to produce ed25519.PrivateKey from %T: %w`, src, err)
   138  		}
   139  		src = &raw
   140  	}
   141  
   142  	var ptr *ed25519.PrivateKey
   143  	switch src := src.(type) {
   144  	case ed25519.PrivateKey:
   145  		ptr = &src
   146  	case *ed25519.PrivateKey:
   147  		ptr = src
   148  	default:
   149  		return fmt.Errorf(`expected ed25519.PrivateKey or *ed25519.PrivateKey, got %T`, src)
   150  	}
   151  	return blackmagic.AssignIfCompatible(dst, ptr)
   152  }
   153  
   154  func Ed25519PublicKey(dst, src interface{}) error {
   155  	if jwkKey, ok := src.(jwk.Key); ok {
   156  		pk, err := jwk.PublicRawKeyOf(jwkKey)
   157  		if err != nil {
   158  			return fmt.Errorf(`keyconv: failed to produce public key from %T: %w`, src, err)
   159  		}
   160  		src = pk
   161  	}
   162  
   163  	switch key := src.(type) {
   164  	case ed25519.PrivateKey:
   165  		src = key.Public()
   166  	case *ed25519.PrivateKey:
   167  		src = key.Public()
   168  	}
   169  
   170  	var ptr *ed25519.PublicKey
   171  	switch src := src.(type) {
   172  	case ed25519.PublicKey:
   173  		ptr = &src
   174  	case *ed25519.PublicKey:
   175  		ptr = src
   176  	case *crypto.PublicKey:
   177  		tmp, ok := (*src).(ed25519.PublicKey)
   178  		if !ok {
   179  			return fmt.Errorf(`failed to retrieve ed25519.PublicKey out of *crypto.PublicKey`)
   180  		}
   181  		ptr = &tmp
   182  	case crypto.PublicKey:
   183  		tmp, ok := src.(ed25519.PublicKey)
   184  		if !ok {
   185  			return fmt.Errorf(`failed to retrieve ed25519.PublicKey out of crypto.PublicKey`)
   186  		}
   187  		ptr = &tmp
   188  	default:
   189  		return fmt.Errorf(`expected ed25519.PublicKey or *ed25519.PublicKey, got %T`, src)
   190  	}
   191  	return blackmagic.AssignIfCompatible(dst, ptr)
   192  }