1
2
3
4
5
6
7 package rsa
8
9 import (
10 "crypto/internal/boring"
11 "crypto/internal/boring/bbig"
12 "crypto/internal/boring/bcache"
13 "math/big"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 type boringPub struct {
30 key *boring.PublicKeyRSA
31 orig PublicKey
32 }
33
34 var pubCache bcache.Cache[PublicKey, boringPub]
35 var privCache bcache.Cache[PrivateKey, boringPriv]
36
37 func init() {
38 pubCache.Register()
39 privCache.Register()
40 }
41
42 func boringPublicKey(pub *PublicKey) (*boring.PublicKeyRSA, error) {
43 b := pubCache.Get(pub)
44 if b != nil && publicKeyEqual(&b.orig, pub) {
45 return b.key, nil
46 }
47
48 b = new(boringPub)
49 b.orig = copyPublicKey(pub)
50 key, err := boring.NewPublicKeyRSA(bbig.Enc(b.orig.N), bbig.Enc(big.NewInt(int64(b.orig.E))))
51 if err != nil {
52 return nil, err
53 }
54 b.key = key
55 pubCache.Put(pub, b)
56 return key, nil
57 }
58
59 type boringPriv struct {
60 key *boring.PrivateKeyRSA
61 orig PrivateKey
62 }
63
64 func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyRSA, error) {
65 b := privCache.Get(priv)
66 if b != nil && privateKeyEqual(&b.orig, priv) {
67 return b.key, nil
68 }
69
70 b = new(boringPriv)
71 b.orig = copyPrivateKey(priv)
72
73 var N, E, D, P, Q, Dp, Dq, Qinv *big.Int
74 N = b.orig.N
75 E = big.NewInt(int64(b.orig.E))
76 D = b.orig.D
77 if len(b.orig.Primes) == 2 {
78 P = b.orig.Primes[0]
79 Q = b.orig.Primes[1]
80 Dp = b.orig.Precomputed.Dp
81 Dq = b.orig.Precomputed.Dq
82 Qinv = b.orig.Precomputed.Qinv
83 }
84 key, err := boring.NewPrivateKeyRSA(bbig.Enc(N), bbig.Enc(E), bbig.Enc(D), bbig.Enc(P), bbig.Enc(Q), bbig.Enc(Dp), bbig.Enc(Dq), bbig.Enc(Qinv))
85 if err != nil {
86 return nil, err
87 }
88 b.key = key
89 privCache.Put(priv, b)
90 return key, nil
91 }
92
93 func publicKeyEqual(k1, k2 *PublicKey) bool {
94 return k1.N != nil &&
95 k1.N.Cmp(k2.N) == 0 &&
96 k1.E == k2.E
97 }
98
99 func copyPublicKey(k *PublicKey) PublicKey {
100 return PublicKey{
101 N: new(big.Int).Set(k.N),
102 E: k.E,
103 }
104 }
105
106 func privateKeyEqual(k1, k2 *PrivateKey) bool {
107 return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
108 k1.D.Cmp(k2.D) == 0
109 }
110
111 func copyPrivateKey(k *PrivateKey) PrivateKey {
112 dst := PrivateKey{
113 PublicKey: copyPublicKey(&k.PublicKey),
114 D: new(big.Int).Set(k.D),
115 }
116 dst.Primes = make([]*big.Int, len(k.Primes))
117 for i, p := range k.Primes {
118 dst.Primes[i] = new(big.Int).Set(p)
119 }
120 if x := k.Precomputed.Dp; x != nil {
121 dst.Precomputed.Dp = new(big.Int).Set(x)
122 }
123 if x := k.Precomputed.Dq; x != nil {
124 dst.Precomputed.Dq = new(big.Int).Set(x)
125 }
126 if x := k.Precomputed.Qinv; x != nil {
127 dst.Precomputed.Qinv = new(big.Int).Set(x)
128 }
129 return dst
130 }
131
View as plain text