...

Source file src/github.com/lestrrat-go/jwx/jwk/rsa.go

Documentation: github.com/lestrrat-go/jwx/jwk

     1  package jwk
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/rsa"
     6  	"encoding/binary"
     7  	"fmt"
     8  	"math/big"
     9  
    10  	"github.com/lestrrat-go/blackmagic"
    11  	"github.com/lestrrat-go/jwx/internal/base64"
    12  	"github.com/lestrrat-go/jwx/internal/pool"
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  func (k *rsaPrivateKey) FromRaw(rawKey *rsa.PrivateKey) error {
    17  	k.mu.Lock()
    18  	defer k.mu.Unlock()
    19  
    20  	d, err := bigIntToBytes(rawKey.D)
    21  	if err != nil {
    22  		return errors.Wrap(err, `invalid rsa.PrivateKey`)
    23  	}
    24  	k.d = d
    25  
    26  	l := len(rawKey.Primes)
    27  
    28  	if l < 0 /* I know, I'm being paranoid */ || l > 2 {
    29  		return fmt.Errorf(`invalid number of primes in rsa.PrivateKey: need 0 to 2, but got %d`, len(rawKey.Primes))
    30  	}
    31  
    32  	if l > 0 {
    33  		p, err := bigIntToBytes(rawKey.Primes[0])
    34  		if err != nil {
    35  			return fmt.Errorf(`invalid rsa.PrivateKey: %w`, err)
    36  		}
    37  		k.p = p
    38  	}
    39  
    40  	if l > 1 {
    41  		q, err := bigIntToBytes(rawKey.Primes[1])
    42  		if err != nil {
    43  			return fmt.Errorf(`invalid rsa.PrivateKey: %w`, err)
    44  		}
    45  		k.q = q
    46  	}
    47  
    48  	// dp, dq, qi are optional values
    49  	if v, err := bigIntToBytes(rawKey.Precomputed.Dp); err == nil {
    50  		k.dp = v
    51  	}
    52  	if v, err := bigIntToBytes(rawKey.Precomputed.Dq); err == nil {
    53  		k.dq = v
    54  	}
    55  	if v, err := bigIntToBytes(rawKey.Precomputed.Qinv); err == nil {
    56  		k.qi = v
    57  	}
    58  
    59  	// public key part
    60  	n, e, err := rsaPublicKeyByteValuesFromRaw(&rawKey.PublicKey)
    61  	if err != nil {
    62  		return errors.Wrap(err, `invalid rsa.PrivateKey`)
    63  	}
    64  	k.n = n
    65  	k.e = e
    66  
    67  	return nil
    68  }
    69  
    70  func rsaPublicKeyByteValuesFromRaw(rawKey *rsa.PublicKey) ([]byte, []byte, error) {
    71  	n, err := bigIntToBytes(rawKey.N)
    72  	if err != nil {
    73  		return nil, nil, errors.Wrap(err, `invalid rsa.PublicKey`)
    74  	}
    75  
    76  	data := make([]byte, 8)
    77  	binary.BigEndian.PutUint64(data, uint64(rawKey.E))
    78  	i := 0
    79  	for ; i < len(data); i++ {
    80  		if data[i] != 0x0 {
    81  			break
    82  		}
    83  	}
    84  	return n, data[i:], nil
    85  }
    86  
    87  func (k *rsaPublicKey) FromRaw(rawKey *rsa.PublicKey) error {
    88  	k.mu.Lock()
    89  	defer k.mu.Unlock()
    90  
    91  	n, e, err := rsaPublicKeyByteValuesFromRaw(rawKey)
    92  	if err != nil {
    93  		return errors.Wrap(err, `invalid rsa.PrivateKey`)
    94  	}
    95  	k.n = n
    96  	k.e = e
    97  
    98  	return nil
    99  }
   100  
   101  func (k *rsaPrivateKey) Raw(v interface{}) error {
   102  	k.mu.RLock()
   103  	defer k.mu.RUnlock()
   104  
   105  	var d, q, p big.Int // note: do not use from sync.Pool
   106  
   107  	d.SetBytes(k.d)
   108  	q.SetBytes(k.q)
   109  	p.SetBytes(k.p)
   110  
   111  	// optional fields
   112  	var dp, dq, qi *big.Int
   113  	if len(k.dp) > 0 {
   114  		dp = &big.Int{} // note: do not use from sync.Pool
   115  		dp.SetBytes(k.dp)
   116  	}
   117  
   118  	if len(k.dq) > 0 {
   119  		dq = &big.Int{} // note: do not use from sync.Pool
   120  		dq.SetBytes(k.dq)
   121  	}
   122  
   123  	if len(k.qi) > 0 {
   124  		qi = &big.Int{} // note: do not use from sync.Pool
   125  		qi.SetBytes(k.qi)
   126  	}
   127  
   128  	var key rsa.PrivateKey
   129  
   130  	pubk := newRSAPublicKey()
   131  	pubk.n = k.n
   132  	pubk.e = k.e
   133  	if err := pubk.Raw(&key.PublicKey); err != nil {
   134  		return errors.Wrap(err, `failed to materialize RSA public key`)
   135  	}
   136  
   137  	key.D = &d
   138  	key.Primes = []*big.Int{&p, &q}
   139  
   140  	if dp != nil {
   141  		key.Precomputed.Dp = dp
   142  	}
   143  	if dq != nil {
   144  		key.Precomputed.Dq = dq
   145  	}
   146  	if qi != nil {
   147  		key.Precomputed.Qinv = qi
   148  	}
   149  	key.Precomputed.CRTValues = []rsa.CRTValue{}
   150  
   151  	return blackmagic.AssignIfCompatible(v, &key)
   152  }
   153  
   154  // Raw takes the values stored in the Key object, and creates the
   155  // corresponding *rsa.PublicKey object.
   156  func (k *rsaPublicKey) Raw(v interface{}) error {
   157  	k.mu.RLock()
   158  	defer k.mu.RUnlock()
   159  
   160  	var key rsa.PublicKey
   161  
   162  	n := pool.GetBigInt()
   163  	e := pool.GetBigInt()
   164  	defer pool.ReleaseBigInt(e)
   165  
   166  	n.SetBytes(k.n)
   167  	e.SetBytes(k.e)
   168  
   169  	key.N = n
   170  	key.E = int(e.Int64())
   171  
   172  	return blackmagic.AssignIfCompatible(v, &key)
   173  }
   174  
   175  func makeRSAPublicKey(v interface {
   176  	makePairs() []*HeaderPair
   177  }) (Key, error) {
   178  	newKey := NewRSAPublicKey()
   179  
   180  	// Iterate and copy everything except for the bits that should not be in the public key
   181  	for _, pair := range v.makePairs() {
   182  		switch pair.Key {
   183  		case RSADKey, RSADPKey, RSADQKey, RSAPKey, RSAQKey, RSAQIKey:
   184  			continue
   185  		default:
   186  			//nolint:forcetypeassert
   187  			key := pair.Key.(string)
   188  			if err := newKey.Set(key, pair.Value); err != nil {
   189  				return nil, errors.Wrapf(err, `failed to set field %q`, key)
   190  			}
   191  		}
   192  	}
   193  
   194  	return newKey, nil
   195  }
   196  
   197  func (k *rsaPrivateKey) PublicKey() (Key, error) {
   198  	return makeRSAPublicKey(k)
   199  }
   200  
   201  func (k *rsaPublicKey) PublicKey() (Key, error) {
   202  	return makeRSAPublicKey(k)
   203  }
   204  
   205  // Thumbprint returns the JWK thumbprint using the indicated
   206  // hashing algorithm, according to RFC 7638
   207  func (k rsaPrivateKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
   208  	k.mu.RLock()
   209  	defer k.mu.RUnlock()
   210  
   211  	var key rsa.PrivateKey
   212  	if err := k.Raw(&key); err != nil {
   213  		return nil, errors.Wrap(err, `failed to materialize RSA private key`)
   214  	}
   215  	return rsaThumbprint(hash, &key.PublicKey)
   216  }
   217  
   218  func (k rsaPublicKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
   219  	k.mu.RLock()
   220  	defer k.mu.RUnlock()
   221  
   222  	var key rsa.PublicKey
   223  	if err := k.Raw(&key); err != nil {
   224  		return nil, errors.Wrap(err, `failed to materialize RSA public key`)
   225  	}
   226  	return rsaThumbprint(hash, &key)
   227  }
   228  
   229  func rsaThumbprint(hash crypto.Hash, key *rsa.PublicKey) ([]byte, error) {
   230  	buf := pool.GetBytesBuffer()
   231  	defer pool.ReleaseBytesBuffer(buf)
   232  
   233  	buf.WriteString(`{"e":"`)
   234  	buf.WriteString(base64.EncodeUint64ToString(uint64(key.E)))
   235  	buf.WriteString(`","kty":"RSA","n":"`)
   236  	buf.WriteString(base64.EncodeToString(key.N.Bytes()))
   237  	buf.WriteString(`"}`)
   238  
   239  	h := hash.New()
   240  	if _, err := buf.WriteTo(h); err != nil {
   241  		return nil, errors.Wrap(err, "failed to write rsaThumbprint")
   242  	}
   243  	return h.Sum(nil), nil
   244  }
   245  

View as plain text