From 0736218cbf31a82766e76f5e230b5f0cca577d3f Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 18 Jan 2026 14:27:07 -0600 Subject: [PATCH 1/3] wip: biggie --- crypto/internal/bigmod/nat.go | 53 ++++++++++++++-- crypto/internal/bigmod/nat_test.go | 12 ++-- crypto/json/rsa.go | 6 +- crypto/json/rsa_test.go | 2 +- crypto/rsa/equal_test.go | 7 +-- crypto/rsa/pss_test.go | 7 +-- crypto/rsa/rsa.go | 43 +++++++------ crypto/rsa/rsa_test.go | 51 ++++++++++------ crypto/ssl3/cryptobyte/asn1.go | 2 +- crypto/ssl3/tls/handshake_server_test.go | 2 +- crypto/ssl3/tls/key_agreement.go | 19 +++--- crypto/x509/parser.go | 3 +- crypto/x509/pkcs1.go | 44 +++++++++---- crypto/x509/x509_test.go | 61 +++++++++++-------- encoding/asn1/asn1.go | 31 ++++++++-- go.mod | 1 + go.sum | 2 + x/crypto/cryptobyte/asn1.go | 11 +++- x/crypto/openpgp/packet/encrypted_key_test.go | 2 +- x/crypto/openpgp/packet/public_key.go | 14 ++--- x/crypto/openpgp/packet/public_key_v3.go | 35 ++++++----- x/crypto/ssh/agent/client.go | 8 ++- x/crypto/ssh/agent/server.go | 4 +- x/crypto/ssh/keys.go | 20 +++--- 24 files changed, 284 insertions(+), 156 deletions(-) diff --git a/crypto/internal/bigmod/nat.go b/crypto/internal/bigmod/nat.go index 8b2621e6330..25716bccd89 100644 --- a/crypto/internal/bigmod/nat.go +++ b/crypto/internal/bigmod/nat.go @@ -6,9 +6,10 @@ package bigmod import ( "errors" - "github.com/runZeroInc/excrypto/internal/byteorder" "math/big" "math/bits" + + "github.com/runZeroInc/excrypto/internal/byteorder" ) const ( @@ -25,8 +26,10 @@ type choice uint func not(c choice) choice { return 1 ^ c } -const yes = choice(1) -const no = choice(0) +const ( + yes = choice(1) + no = choice(0) +) // ctMask is all 1s if on is yes, and all 0s otherwise. func ctMask(on choice) uint { return -uint(on) } @@ -53,8 +56,10 @@ type Nat struct { // preallocTarget is the size in bits of the numbers used to implement the most // common and most performant RSA key size. It's also enough to cover some of // the operations of key sizes up to 4096. -const preallocTarget = 2048 -const preallocLimbs = (preallocTarget + _W - 1) / _W +const ( + preallocTarget = 2048 + preallocLimbs = (preallocTarget + _W - 1) / _W +) // NewNat returns a new nat with a size of zero, just like new(Nat), but with // the preallocated capacity to hold a number of up to preallocTarget bits. @@ -771,7 +776,43 @@ func (out *Nat) Exp(x *Nat, e []byte, m *Modulus) *Nat { // // The output will be resized to the size of m and overwritten. x must already // be reduced modulo m. This leaks the exponent through timing side-channels. -func (out *Nat) ExpShortVarTime(x *Nat, e uint, m *Modulus) *Nat { +func (out *Nat) ExpShortVarTime(x *Nat, e *big.Int, m *Modulus) *Nat { + // For short exponents, precomputing a table and using a window like in Exp + // doesn't pay off. Instead, we do a simple conditional square-and-multiply + // chain, skipping the initial run of zeroes. + xR := NewNat().set(x).montgomeryRepresentation(m) + out.set(xR) + + // Convert the big.Int exponent to binary representation + expBits := e.Bytes() + for i := 0; i < len(expBits); i++ { + byteVal := expBits[i] + for j := 7; j >= 0; j-- { + // Square the result + out.montgomeryMul(out, out, m) + + // Multiply if the current bit is set + if (byteVal>>j)&1 == 1 { + out.montgomeryMul(out, xR, m) + } + } + } + + resNew := out.montgomeryReduction(m) + resOld := out.ExpShortVarTimeOrig(x, uint(e.Uint64()), m) + if resNew.Equal(resOld) == no { + panic("XXX: bigmod: ExpShortVarTime produced different result than ExpShortVarTimeOrig") + } + return resNew +} + +// ExpShortVarTime calculates out = x^e mod m. +// +// The output will be resized to the size of m and overwritten. x must already +// be reduced modulo m. This leaks the exponent through timing side-channels. +// +// m must be odd, or ExpShortVarTime will panic. +func (out *Nat) ExpShortVarTimeOrig(x *Nat, e uint, m *Modulus) *Nat { // For short exponents, precomputing a table and using a window like in Exp // doesn't pay off. Instead, we do a simple conditional square-and-multiply // chain, skipping the initial run of zeroes. diff --git a/crypto/internal/bigmod/nat_test.go b/crypto/internal/bigmod/nat_test.go index 7a956e3a57d..fcc4a61ed5b 100644 --- a/crypto/internal/bigmod/nat_test.go +++ b/crypto/internal/bigmod/nat_test.go @@ -131,9 +131,12 @@ func TestModulusAndNatSizes(t *testing.T) { // modulus strips leading zeroes and nat does not. m := modulusFromBytes([]byte{ 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) - xb := []byte{0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe} + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }) + xb := []byte{ + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + } natFromBytes(xb).ExpandFor(m) // must not panic for shrinking NewNat().SetBytes(xb, m) } @@ -303,7 +306,8 @@ func TestExpShort(t *testing.T) { m := modulusFromBytes([]byte{13}) x := &Nat{[]uint{3}} out := &Nat{[]uint{0}} - out.ExpShortVarTime(x, 12, m) + e := big.NewInt(12) + out.ExpShortVarTime(x, e, m) expected := &Nat{[]uint{1}} if out.Equal(expected) != 1 { t.Errorf("%+v != %+v", out, expected) diff --git a/crypto/json/rsa.go b/crypto/json/rsa.go index a44763c172f..849c06e8d22 100644 --- a/crypto/json/rsa.go +++ b/crypto/json/rsa.go @@ -28,9 +28,9 @@ type RSAPublicKey struct { } type auxRSAPublicKey struct { - Exponent int `json:"exponent"` - Modulus []byte `json:"modulus"` - Length int `json:"length"` + Exponent *big.Int `json:"exponent"` + Modulus []byte `json:"modulus"` + Length int `json:"length"` } // RSAClientParams are the TLS key exchange parameters for RSA keys. diff --git a/crypto/json/rsa_test.go b/crypto/json/rsa_test.go index d4fe5e77ff1..5a778f3cb91 100644 --- a/crypto/json/rsa_test.go +++ b/crypto/json/rsa_test.go @@ -37,7 +37,7 @@ var _ = Suite(&RSASuite{}) func (s *RSASuite) SetUpTest(c *C) { s.pk4096 = new(RSAPublicKey) s.pk4096.PublicKey = new(rsa.PublicKey) - s.pk4096.E = 65537 + s.pk4096.E = big.NewInt(65537) s.pk4096.N = big.NewInt(0).SetBytes(test4096Modulus) } diff --git a/crypto/rsa/equal_test.go b/crypto/rsa/equal_test.go index f4ebad79e2f..9f3cdd603e9 100644 --- a/crypto/rsa/equal_test.go +++ b/crypto/rsa/equal_test.go @@ -5,9 +5,8 @@ package rsa_test import ( - "testing" - "crypto/rand" + "testing" "github.com/runZeroInc/excrypto/crypto" "github.com/runZeroInc/excrypto/crypto/rsa" @@ -37,10 +36,10 @@ func TestEqual(t *testing.T) { t.Fatal(err) } if !public.Equal(decoded.(crypto.Signer).Public()) { - t.Errorf("public key is not equal to itself after decoding: %v", public) + t.Errorf("public key is not equal to itself after decoding: pre: %#v. post: %#v", public, decoded.(crypto.Signer).Public()) } if !private.Equal(decoded) { - t.Errorf("private key is not equal to itself after decoding: %v", private) + t.Errorf("private key is not equal to itself after decoding: pre: %#v. post: %#v", private, decoded) } other, _ := rsa.GenerateKey(rand.Reader, 512) diff --git a/crypto/rsa/pss_test.go b/crypto/rsa/pss_test.go index e01da05ee97..94554e7a62a 100644 --- a/crypto/rsa/pss_test.go +++ b/crypto/rsa/pss_test.go @@ -8,6 +8,7 @@ import ( "bufio" "bytes" "compress/bzip2" + "crypto/rand" "encoding/hex" "math/big" "os" @@ -15,8 +16,6 @@ import ( "strings" "testing" - "crypto/rand" - "github.com/runZeroInc/excrypto/crypto" . "github.com/runZeroInc/excrypto/crypto/rsa" "github.com/runZeroInc/excrypto/crypto/sha1" @@ -145,7 +144,7 @@ func TestPSSGolden(t *testing.T) { continue } key.N = bigFromHex(nHex) - key.E = intFromHex(<-values) + key.E = bigFromHex(<-values) // We don't care for d, p, q, dP, dQ or qInv. for i := 0; i < 6; i++ { <-values @@ -202,7 +201,7 @@ func TestPSSNilOpts(t *testing.T) { } func TestPSSSigning(t *testing.T) { - var saltLengthCombinations = []struct { + saltLengthCombinations := []struct { signSaltLength, verifySaltLength int good bool }{ diff --git a/crypto/rsa/rsa.go b/crypto/rsa/rsa.go index 7331bb54257..76c69deca43 100644 --- a/crypto/rsa/rsa.go +++ b/crypto/rsa/rsa.go @@ -25,14 +25,13 @@ package rsa import ( + "crypto/rand" "errors" "hash" "io" "math" "math/big" - "crypto/rand" - "github.com/runZeroInc/excrypto/crypto" "github.com/runZeroInc/excrypto/crypto/internal/bigmod" "github.com/runZeroInc/excrypto/crypto/internal/boring" @@ -50,7 +49,7 @@ var bigOne = big.NewInt(1) // exponent E nor the precise bit size of N are similarly protected. type PublicKey struct { N *big.Int // modulus - E int // public exponent + E *big.Int // public exponent } // Any methods implemented on PublicKey might need to also be implemented on @@ -68,7 +67,7 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool { if !ok { return false } - return bigIntEqual(pub.N, xx.N) && pub.E == xx.E + return bigIntEqual(pub.N, xx.N) && bigIntEqual(pub.E, xx.E) } // OAEPOptions is an interface for passing options to OAEP decryption using the @@ -92,6 +91,8 @@ var ( errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large") ) +/* +// The original checkPub() is disabled to enable wild values for E // checkPub sanity checks the public key before we use it. // We require pub.E to fit into a 32-bit integer so that we // do not have different behavior depending on whether @@ -101,12 +102,23 @@ func checkPub(pub *PublicKey) error { if pub.N == nil { return errPublicModulus } + if pub.E < 2 { return errPublicExponentSmall } if pub.E > 1<<31-1 { return errPublicExponentLarge } + + return nil +} +*/ + +// checkPub provides minimal checks on the public key. +func checkPub(pub *PublicKey) error { + if pub.N == nil { + return errPublicModulus + } return nil } @@ -256,7 +268,7 @@ func (priv *PrivateKey) Validate() error { // exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1 // mod p. Thus a^de ≡ a mod n for all a coprime to n, as required. congruence := new(big.Int) - de := new(big.Int).SetInt64(int64(priv.E)) + de := new(big.Int).Set(priv.E) de.Mul(de, priv.D) for _, prime := range priv.Primes { pminus1 := new(big.Int).Sub(prime, bigOne) @@ -313,10 +325,6 @@ func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey Dp := bbig.Dec(bDp) Dq := bbig.Dec(bDq) Qinv := bbig.Dec(bQinv) - e64 := E.Int64() - if !E.IsInt64() || int64(int(e64)) != e64 { - return nil, errors.New("crypto/rsa: generated key exponent too large") - } mn, err := bigmod.NewModulusFromBig(N) if err != nil { @@ -334,7 +342,7 @@ func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey key := &PrivateKey{ PublicKey: PublicKey{ N: N, - E: int(e64), + E: new(big.Int).Set(E), }, D: D, Primes: []*big.Int{P, Q}, @@ -352,7 +360,7 @@ func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey } priv := new(PrivateKey) - priv.E = 65537 + priv.E = big.NewInt(65537) if nprimes < 2 { return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2") @@ -426,7 +434,7 @@ NextSetOfPrimes: } priv.D = new(big.Int) - e := big.NewInt(int64(priv.E)) + e := new(big.Int).Set(priv.E) ok := priv.D.ModInverse(e, totient) if ok != nil { @@ -491,8 +499,7 @@ func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) { if err != nil { return nil, err } - e := uint(pub.E) - + e := new(big.Int).Set(pub.E) return bigmod.NewNat().ExpShortVarTime(m, e, N).Bytes(N), nil } @@ -633,8 +640,10 @@ func (priv *PrivateKey) Precompute() { } } -const withCheck = true -const noCheck = false +const ( + withCheck = true + noCheck = false +) // decrypt performs an RSA decryption of ciphertext into out. If check is true, // m^e is calculated and compared with ciphertext, in order to defend against @@ -687,7 +696,7 @@ func decrypt(priv *PrivateKey, ciphertext []byte, check bool) ([]byte, error) { } if check { - c1 := bigmod.NewNat().ExpShortVarTime(m, uint(priv.E), N) + c1 := bigmod.NewNat().ExpShortVarTime(m, priv.E, N) if c1.Equal(c) != 1 { return nil, ErrDecryption } diff --git a/crypto/rsa/rsa_test.go b/crypto/rsa/rsa_test.go index 7f6475684f7..b3499d2aa38 100644 --- a/crypto/rsa/rsa_test.go +++ b/crypto/rsa/rsa_test.go @@ -7,6 +7,7 @@ package rsa_test import ( "bufio" "bytes" + "crypto/rand" "encoding/pem" "flag" "fmt" @@ -14,8 +15,6 @@ import ( "strings" "testing" - "crypto/rand" - "github.com/runZeroInc/excrypto/crypto" "github.com/runZeroInc/excrypto/crypto/internal/boring" . "github.com/runZeroInc/excrypto/crypto/rsa" @@ -631,7 +630,7 @@ type testEncryptOAEPMessage struct { type testEncryptOAEPStruct struct { modulus string - e int + e *big.Int d string msgs []testEncryptOAEPMessage } @@ -749,22 +748,26 @@ func TestEncryptDecryptOAEP(t *testing.T) { // testEncryptOAEPData contains a subset of the vectors from RSA's "Test vectors for RSA-OAEP". var testEncryptOAEPData = []testEncryptOAEPStruct{ // Key 1 - {"a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb", - 65537, + { + "a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb", + big.NewInt(65537), "53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1", []testEncryptOAEPMessage{ // Example 1.1 { - []byte{0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, + []byte{ + 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23, 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34, }, - []byte{0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, + []byte{ + 0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1, 0xdd, 0xa0, 0xa5, 0xef, }, - []byte{0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, + []byte{ + 0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f, 0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb, 0x21, 0x69, 0x6d, @@ -783,16 +786,19 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ }, // Example 1.2 { - []byte{0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, + []byte{ + 0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9, 0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5, }, - []byte{0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, + []byte{ + 0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25, 0xfe, 0x4f, 0xe3, 0x5f, }, - []byte{0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, + []byte{ + 0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf, 0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11, 0x65, 0x98, 0x8d, @@ -811,7 +817,8 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ }, // Example 1.3 { - []byte{0xd9, 0x4a, 0xe0, 0x83, 0x2e, 0x64, 0x45, 0xce, + []byte{ + 0xd9, 0x4a, 0xe0, 0x83, 0x2e, 0x64, 0x45, 0xce, 0x42, 0x33, 0x1c, 0xb0, 0x6d, 0x53, 0x1a, 0x82, 0xb1, 0xdb, 0x4b, 0xaa, 0xd3, 0x0f, 0x74, 0x6d, 0xc9, 0x16, 0xdf, 0x24, 0xd4, 0xe3, 0xc2, 0x45, 0x1f, 0xff, 0x59, @@ -819,11 +826,13 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ 0x46, 0xcf, 0x69, 0x9d, 0xfd, 0x81, 0x8c, 0x6e, 0x97, 0xb0, 0x51, }, - []byte{0x25, 0x14, 0xdf, 0x46, 0x95, 0x75, 0x5a, 0x67, + []byte{ + 0x25, 0x14, 0xdf, 0x46, 0x95, 0x75, 0x5a, 0x67, 0xb2, 0x88, 0xea, 0xf4, 0x90, 0x5c, 0x36, 0xee, 0xc6, 0x6f, 0xd2, 0xfd, }, - []byte{0x42, 0x37, 0x36, 0xed, 0x03, 0x5f, 0x60, 0x26, + []byte{ + 0x42, 0x37, 0x36, 0xed, 0x03, 0x5f, 0x60, 0x26, 0xaf, 0x27, 0x6c, 0x35, 0xc0, 0xb3, 0x74, 0x1b, 0x36, 0x5e, 0x5f, 0x76, 0xca, 0x09, 0x1b, 0x4e, 0x8c, 0x29, 0xe2, 0xf0, 0xbe, 0xfe, 0xe6, 0x03, 0x59, 0x5a, 0xa8, @@ -843,22 +852,26 @@ var testEncryptOAEPData = []testEncryptOAEPStruct{ }, }, // Key 10 - {"ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb", - 65537, + { + "ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb", + big.NewInt(65537), "056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e79", []testEncryptOAEPMessage{ // Example 10.1 { - []byte{0x8b, 0xba, 0x6b, 0xf8, 0x2a, 0x6c, 0x0f, 0x86, + []byte{ + 0x8b, 0xba, 0x6b, 0xf8, 0x2a, 0x6c, 0x0f, 0x86, 0xd5, 0xf1, 0x75, 0x6e, 0x97, 0x95, 0x68, 0x70, 0xb0, 0x89, 0x53, 0xb0, 0x6b, 0x4e, 0xb2, 0x05, 0xbc, 0x16, 0x94, 0xee, }, - []byte{0x47, 0xe1, 0xab, 0x71, 0x19, 0xfe, 0xe5, 0x6c, + []byte{ + 0x47, 0xe1, 0xab, 0x71, 0x19, 0xfe, 0xe5, 0x6c, 0x95, 0xee, 0x5e, 0xaa, 0xd8, 0x6f, 0x40, 0xd0, 0xaa, 0x63, 0xbd, 0x33, }, - []byte{0x53, 0xea, 0x5d, 0xc0, 0x8c, 0xd2, 0x60, 0xfb, + []byte{ + 0x53, 0xea, 0x5d, 0xc0, 0x8c, 0xd2, 0x60, 0xfb, 0x3b, 0x85, 0x85, 0x67, 0x28, 0x7f, 0xa9, 0x15, 0x52, 0xc3, 0x0b, 0x2f, 0xeb, 0xfb, 0xa2, 0x13, 0xf0, 0xae, 0x87, 0x70, 0x2d, 0x06, 0x8d, 0x19, 0xba, 0xb0, 0x7f, diff --git a/crypto/ssl3/cryptobyte/asn1.go b/crypto/ssl3/cryptobyte/asn1.go index e12b9d4bef3..a04bb84bf2d 100644 --- a/crypto/ssl3/cryptobyte/asn1.go +++ b/crypto/ssl3/cryptobyte/asn1.go @@ -280,7 +280,7 @@ func (s *String) ReadASN1Integer(out interface{}) bool { return s.readASN1BigInt(out.(*big.Int)) } } - panic("out does not point to an integer type") + panic("out does not point to an integer type: " + reflect.TypeOf(out).Elem().String()) } func checkASN1Integer(bytes []byte) bool { diff --git a/crypto/ssl3/tls/handshake_server_test.go b/crypto/ssl3/tls/handshake_server_test.go index 2c9d315a941..0391d6218ba 100644 --- a/crypto/ssl3/tls/handshake_server_test.go +++ b/crypto/ssl3/tls/handshake_server_test.go @@ -850,7 +850,7 @@ var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a8648 var testRSAPrivateKey = &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"), - E: 65537, + E: big.NewInt(65537), }, D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"), Primes: []*big.Int{ diff --git a/crypto/ssl3/tls/key_agreement.go b/crypto/ssl3/tls/key_agreement.go index edb9345a5d0..44a305cafb7 100644 --- a/crypto/ssl3/tls/key_agreement.go +++ b/crypto/ssl3/tls/key_agreement.go @@ -5,12 +5,11 @@ package tls import ( + "crypto/rand" "errors" "io" "math/big" - "crypto/rand" - "github.com/runZeroInc/excrypto/crypto" "github.com/runZeroInc/excrypto/crypto/dsa" "github.com/runZeroInc/excrypto/crypto/ecdsa" @@ -24,9 +23,11 @@ import ( "github.com/runZeroInc/excrypto/encoding/asn1" ) -var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") -var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") -var errUnexpectedServerKeyExchange = errors.New("tls: unexpected ServerKeyExchange message") +var ( + errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") + errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") + errUnexpectedServerKeyExchange = errors.New("tls: unexpected ServerKeyExchange message") +) // rsaKeyAgreement implements the standard TLS key agreement where the client // encrypts the pre-master secret to the server's public key. @@ -62,7 +63,7 @@ func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certi // Serialize the key parameters to a nice byte array. The byte array can be // positioned later. modulus := ka.privateKey.N.Bytes() - exponent := big.NewInt(int64(ka.privateKey.E)).Bytes() + exponent := new(big.Int).SetBytes(ka.privateKey.E.Bytes()).Bytes() serverRSAParams := make([]byte, 0, 2+len(modulus)+2+len(exponent)) serverRSAParams = append(serverRSAParams, byte(len(modulus)>>8), byte(len(modulus))) serverRSAParams = append(serverRSAParams, modulus...) @@ -138,11 +139,7 @@ func (ka *rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello return errServerKeyExchange } rawExponent := k[0:exponentLength] - exponent := 0 - for _, b := range rawExponent { - exponent <<= 8 - exponent |= int(b) - } + exponent := new(big.Int).SetBytes(rawExponent) ka.publicKey = new(rsa.PublicKey) ka.publicKey.E = exponent ka.publicKey.N = modulus diff --git a/crypto/x509/parser.go b/crypto/x509/parser.go index 4f6c74baa52..6de9909c448 100644 --- a/crypto/x509/parser.go +++ b/crypto/x509/parser.go @@ -247,7 +247,7 @@ func parsePublicKey(keyData *publicKeyInfo) (any, error) { if p.N.Sign() <= 0 { return nil, errors.New("x509: RSA modulus is not a positive number") } - if p.E <= 0 { + if p.E.Cmp(big.NewInt(0)) <= 0 { return nil, errors.New("x509: RSA public exponent is not a positive number") } } @@ -834,7 +834,6 @@ func processExtensions(out *Certificate) error { out.OtherNames, out.DNSNames, out.EmailAddresses, out.URIs, out.DirectoryNames, out.EDIPartyNames, out.IPAddresses, out.RegisteredIDs, out.FailedToParseNames, err = parseGeneralNames(e.Value) - // TODO: verify that parseGeneralNames handles the same cases as parseSANExtension // out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value) if err != nil { diff --git a/crypto/x509/pkcs1.go b/crypto/x509/pkcs1.go index 86d99e6f938..85495f2ee22 100644 --- a/crypto/x509/pkcs1.go +++ b/crypto/x509/pkcs1.go @@ -10,16 +10,18 @@ import ( "github.com/runZeroInc/excrypto/crypto/rsa" "github.com/runZeroInc/excrypto/encoding/asn1" + "github.com/sirupsen/logrus" ) // pkcs1PrivateKey is a structure which mirrors the PKCS #1 ASN.1 for an RSA private key. type pkcs1PrivateKey struct { Version int N *big.Int - E int - D *big.Int - P *big.Int - Q *big.Int + // E int + E *big.Int + D *big.Int + P *big.Int + Q *big.Int // We ignore these values, if present, because rsa will calculate them. Dp *big.Int `asn1:"optional"` Dq *big.Int `asn1:"optional"` @@ -39,7 +41,13 @@ type pkcs1AdditionalRSAPrime struct { // pkcs1PublicKey reflects the ASN.1 structure of a PKCS #1 public key. type pkcs1PublicKey struct { N *big.Int - E int + E *big.Int +} + +// pkcs1PublicKeyOld reflects the ASN.1 structure of a PKCS #1 public key. +type pkcs1PublicKeyOld struct { + N *big.Int + E uint } // ParsePKCS1PrivateKey parses an [RSA] private key in PKCS #1, ASN.1 DER form. @@ -113,7 +121,7 @@ func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte { priv := pkcs1PrivateKey{ Version: version, N: key.N, - E: key.PublicKey.E, + E: new(big.Int).Set(key.PublicKey.E), D: key.D, P: key.Primes[0], Q: key.Primes[1], @@ -138,24 +146,34 @@ func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte { // This kind of key is commonly encoded in PEM blocks of type "RSA PUBLIC KEY". func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error) { var pub pkcs1PublicKey + var pubOld pkcs1PublicKeyOld rest, err := asn1.Unmarshal(der, &pub) if err != nil { + logrus.Errorf("failed to decode pkcs1PublicKey: %v", err) if _, err := asn1.Unmarshal(der, &publicKeyInfo{}); err == nil { return nil, errors.New("x509: failed to parse public key (use ParsePKIXPublicKey instead for this key format)") } + logrus.Errorf("failed to decode pkcs1PublicKeyInfo: %v", err) + if _, err := asn1.Unmarshal(der, &pubOld); err == nil { + return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKeyOld instead for this key format)") + } + logrus.Errorf("failed to decode pkcs1PublicKeyOld: %v", err) + return nil, err } if len(rest) > 0 { return nil, asn1.SyntaxError{Msg: "trailing data"} } - if pub.N.Sign() <= 0 || pub.E <= 0 { - return nil, errors.New("x509: public key contains zero or negative value") - } - if pub.E > 1<<31-1 { - return nil, errors.New("x509: public key contains large public exponent") - } - + // excrypto + /* + if pub.N.Sign() <= 0 || pub.E <= 0 { + return nil, errors.New("x509: public key contains zero or negative value") + } + if pub.E > 1<<31-1 { + return nil, errors.New("x509: public key contains large public exponent") + } + */ return &rsa.PublicKey{ E: pub.E, N: pub.N, diff --git a/crypto/x509/x509_test.go b/crypto/x509/x509_test.go index c89296f4805..8a2dda0fe0b 100644 --- a/crypto/x509/x509_test.go +++ b/crypto/x509/x509_test.go @@ -49,7 +49,7 @@ func TestParsePKCS1PrivateKey(t *testing.T) { return } if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 || - priv.PublicKey.E != rsaPrivateKey.PublicKey.E || + priv.PublicKey.E.Cmp(rsaPrivateKey.PublicKey.E) != 0 || priv.D.Cmp(rsaPrivateKey.D) != 0 || priv.Primes[0].Cmp(rsaPrivateKey.Primes[0]) != 0 || priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 { @@ -65,7 +65,6 @@ func TestParsePKCS1PrivateKey(t *testing.T) { } func TestPKCS1MismatchPublicKeyFormat(t *testing.T) { - const pkixPublicKey = "30820122300d06092a864886f70d01010105000382010f003082010a0282010100dd5a0f37d3ca5232852ccc0e81eebec270e2f2c6c44c6231d852971a0aad00aa7399e9b9de444611083c59ea919a9d76c20a7be131a99045ec19a7bb452d647a72429e66b87e28be9e8187ed1d2a2a01ef3eb2360706bd873b07f2d1f1a72337aab5ec94e983e39107f52c480d404915e84d75a3db2cfd601726a128cb1d7f11492d4bdb53272e652276667220795c709b8a9b4af6489cbf48bb8173b8fb607c834a71b6e8bf2d6aab82af3c8ad7ce16d8dcf58373a6edc427f7484d09744d4c08f4e19ed07adbf6cb31243bc5d0d1145e77a08a6fc5efd208eca67d6abf2d6f38f58b6fdd7c28774fb0cc03fc4935c6e074842d2e1479d3d8787249258719f90203010001" const errorContains = "use ParsePKIXPublicKey instead" derBytes, _ := hex.DecodeString(pkixPublicKey) @@ -175,7 +174,6 @@ MCowBQYDK2VuAyEA5yGXrH/6OzxuWEhEWS01/f4OP+Of3Yrddy6/J1kDTVM= ` func TestPKIXMismatchPublicKeyFormat(t *testing.T) { - const pkcs1PublicKey = "308201080282010100817cfed98bcaa2e2a57087451c7674e0c675686dc33ff1268b0c2a6ee0202dec710858ee1c31bdf5e7783582e8ca800be45f3275c6576adc35d98e26e95bb88ca5beb186f853b8745d88bc9102c5f38753bcda519fb05948d5c77ac429255ff8aaf27d9f45d1586e95e2e9ba8a7cb771b8a09dd8c8fed3f933fd9b439bc9f30c475953418ef25f71a2b6496f53d94d39ce850aa0cc75d445b5f5b4f4ee4db78ab197a9a8d8a852f44529a007ac0ac23d895928d60ba538b16b0b087a7f903ed29770e215019b77eaecc360f35f7ab11b6d735978795b2c4a74e5bdea4dc6594cd67ed752a108e666729a753ab36d6c4f606f8760f507e1765be8cd744007e629020103" const errorContains = "use ParsePKCS1PublicKey instead" derBytes, _ := hex.DecodeString(pkcs1PublicKey) @@ -217,7 +215,7 @@ func bigFromHexString(s string) *big.Int { var rsaPrivateKey = &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ N: bigFromString("124737666279038955318614287965056875799409043964547386061640914307192830334599556034328900586693254156136128122194531292927142396093148164407300419162827624945636708870992355233833321488652786796134504707628792159725681555822420087112284637501705261187690946267527866880072856272532711620639179596808018872997"), - E: 65537, + E: big.NewInt(65537), }, D: bigFromString("69322600686866301945688231018559005300304807960033948687567105312977055197015197977971637657636780793670599180105424702854759606794705928621125408040473426339714144598640466128488132656829419518221592374964225347786430566310906679585739468938549035854760501049443920822523780156843263434219450229353270690889"), Primes: []*big.Int{ @@ -230,7 +228,7 @@ func TestMarshalRSAPrivateKey(t *testing.T) { priv := &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"), - E: 3, + E: big.NewInt(3), }, D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"), Primes: []*big.Int{ @@ -248,7 +246,7 @@ func TestMarshalRSAPrivateKey(t *testing.T) { return } if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 || - priv.PublicKey.E != priv2.PublicKey.E || + priv.PublicKey.E.Cmp(priv2.PublicKey.E) != 0 || priv.D.Cmp(priv2.D) != 0 || len(priv2.Primes) != 3 || priv.Primes[0].Cmp(priv2.Primes[0]) != 0 || @@ -261,14 +259,13 @@ func TestMarshalRSAPrivateKey(t *testing.T) { func TestMarshalRSAPublicKey(t *testing.T) { pub := &rsa.PublicKey{ N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"), - E: 3, } derBytes := MarshalPKCS1PublicKey(pub) pub2, err := ParsePKCS1PublicKey(derBytes) if err != nil { - t.Errorf("ParsePKCS1PublicKey: %s", err) + t.Fatalf("ParsePKCS1PublicKey: %s", err) } - if pub.N.Cmp(pub2.N) != 0 || pub.E != pub2.E { + if pub.N.Cmp(pub2.N) != 0 || pub.E.Cmp(pub2.E) != 0 { t.Errorf("ParsePKCS1PublicKey = %+v, want %+v", pub, pub2) } @@ -286,7 +283,7 @@ func TestMarshalRSAPublicKey(t *testing.T) { if err != nil { t.Errorf("Unmarshal(rsa.PublicKey): %v", err) } - if len(rest) != 0 || pub.N.Cmp(pub3.N) != 0 || pub.E != pub3.E { + if len(rest) != 0 || pub.N.Cmp(pub3.N) != 0 || pub.E.Cmp(pub3.E) != 0 { t.Errorf("Unmarshal(rsa.PublicKey) = %+v, %q want %+v, %q", pub, rest, pub2, []byte(nil)) } @@ -351,7 +348,8 @@ func TestMarshalRSAPublicKey(t *testing.T) { // an error. On 32-bit systems, encoding/asn1 will // return the error. The common substring of both error // is the word “large”. - expectedErrSubstr: "large", + // expectedErrSubstr: "large", + // We support big E now! }, } @@ -2096,19 +2094,22 @@ func TestPKIXNameString(t *testing.T) { rdns := pkix.Name{ Locality: []string{"Gophertown"}, ExtraNames: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}, + }, }.ToRDNSequence() nn := pkix.Name{} nn.FillFromRDNSequence(&rdns) // Check that zero-length non-nil ExtraNames hide Names. extra := []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "backing array"}} + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "backing array"}, + } extraNotNil := pkix.Name{ Locality: []string{"Gophertown"}, ExtraNames: extra[:0], Names: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}, + }, } tests := []struct { @@ -2128,8 +2129,10 @@ func TestPKIXNameString(t *testing.T) { SerialNumber: "RFC 2253", Country: []string{"GB"}, }, "SERIALNUMBER=RFC 2253, C=GB, POSTALCODE=TW9 1DT, ST=Surrey, L=Richmond, STREET=The Square, O=Isode Limited, OU=RFCs, CN=Steve Kille"}, - {certs[0].Subject, - "CN=mail.google.com, O=Google LLC, L=Mountain View, ST=California, C=US"}, + { + certs[0].Subject, + "CN=mail.google.com, O=Google LLC, L=Mountain View, ST=California, C=US", + }, {pkix.Name{ Organization: []string{"#Google, Inc. \n-> 'Alphabet\" "}, Country: []string{"US"}, @@ -2138,26 +2141,31 @@ func TestPKIXNameString(t *testing.T) { CommonName: "foo.com", Organization: []string{"Gopher Industries"}, ExtraNames: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{2, 5, 4, 3}), Value: "bar.com"}}, + {Type: asn1.ObjectIdentifier([]int{2, 5, 4, 3}), Value: "bar.com"}, + }, }, "CN=bar.com, O=Gopher Industries"}, {pkix.Name{ Locality: []string{"Gophertown"}, ExtraNames: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}, + }, }, "1.2.3.4.5=#130a676f6c616e672e6f7267, L=Gophertown"}, // If there are no ExtraNames, the Names are printed instead. {pkix.Name{ Locality: []string{"Gophertown"}, Names: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}, + }, }, "L=Gophertown, 1.2.3.4.5=#130a676f6c616e672e6f7267"}, // If there are both, print only the ExtraNames. {pkix.Name{ Locality: []string{"Gophertown"}, ExtraNames: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}, + }, Names: []pkix.AttributeTypeAndValue{ - {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 6}), Value: "example.com"}}, + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 6}), Value: "example.com"}, + }, }, "1.2.3.4.5=#130a676f6c616e672e6f7267, L=Gophertown"}, } @@ -2411,8 +2419,10 @@ func TestMultipleURLsInCRLDP(t *testing.T) { } } -const hexPKCS1TestPKCS8Key = "30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031" -const hexPKCS1TestECKey = "3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50" +const ( + hexPKCS1TestPKCS8Key = "30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031" + hexPKCS1TestECKey = "3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50" +) var pkcs1MismatchKeyTests = []struct { hexKey string @@ -3595,7 +3605,6 @@ func TestParseUniqueID(t *testing.T) { } func TestSHA1ForCertOnlySuccess(t *testing.T) { - tmpl := &Certificate{ SerialNumber: big.NewInt(1), NotBefore: time.Now().Add(-time.Hour), @@ -3916,11 +3925,11 @@ func TestCertificateOIDPolicies(t *testing.T) { PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, } - var expectPolicyIdentifiers = []asn1.ObjectIdentifier{ + expectPolicyIdentifiers := []asn1.ObjectIdentifier{ []int{1, 2, 3}, } - var expectPolicies = []OID{ + expectPolicies := []OID{ mustNewOIDFromInts(t, []uint64{1, 2, 3}), } diff --git a/encoding/asn1/asn1.go b/encoding/asn1/asn1.go index 2e988f2e6e0..b6e4146a5b2 100644 --- a/encoding/asn1/asn1.go +++ b/encoding/asn1/asn1.go @@ -25,6 +25,7 @@ import ( "math" "math/big" "reflect" + "runtime/debug" "strconv" "strings" "time" @@ -103,7 +104,9 @@ func parseInt64(bytes []byte) (ret int64, err error) { } if len(bytes) > 8 { // We'll overflow an int64 in this case. - err = StructuralError{"integer too large"} + err = StructuralError{"integer too large for 64-bit: " + strconv.Itoa(len(bytes)) + " bytes"} + fmt.Printf("unsupported int size: %d from caller: %s\n\n", len(bytes), debug.Stack()) + return } for bytesRead := 0; bytesRead < len(bytes); bytesRead++ { @@ -128,7 +131,7 @@ func parseInt32(bytes []byte) (int32, error) { return 0, err } if ret64 != int64(int32(ret64)) { - return 0, StructuralError{"integer too large"} + return 0, StructuralError{"integer too large for 32-bit: " + strconv.Itoa(len(bytes)) + " bytes"} } return int32(ret64), nil } @@ -426,8 +429,10 @@ func parsePrintableString(bytes []byte) (ret string, err error) { return } -type asteriskFlag bool -type ampersandFlag bool +type ( + asteriskFlag bool + ampersandFlag bool +) const ( allowAsterisk asteriskFlag = true @@ -698,8 +703,9 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam // If we have run out of data, it may be that there are optional elements at the end. if offset == len(bytes) { + if !setDefaultValue(v, params) { - err = SyntaxError{"sequence truncated"} + err = SyntaxError{fmt.Sprintf("sequence truncated (type=%#v for params %#v, offset=%d, len=%d)", v, params, offset, len(bytes))} } return } @@ -715,6 +721,8 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam err = SyntaxError{"data truncated"} return } + // logrus.Errorf("parseField called for type: %v with tag=%x and %d bytes", fieldType, t.tag, len(bytes)-offset) + var result any if !t.isCompound && t.class == ClassUniversal { innerBytes := bytes[offset : offset+t.length] @@ -731,6 +739,13 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam result, err = parseUTF8String(innerBytes) case TagInteger: result, err = parseInt64(innerBytes) + if errors.Is(err, StructuralError{}) { + var bigIntResult *big.Int + bigIntResult, err = parseBigInt(innerBytes) + if err == nil { + result = bigIntResult + } + } case TagBitString: result, err = parseBitString(innerBytes) case TagOID: @@ -925,6 +940,12 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam parsedInt, err1 := parseInt64(innerBytes) if err1 == nil { val.SetInt(parsedInt) + } else { + // Try big.Int parsing if int64 parsing failed. + parsedInt, err1 := parseBigInt(innerBytes) + if err1 == nil { + val.Set(reflect.ValueOf(parsedInt)) + } } err = err1 } diff --git a/go.mod b/go.mod index 5028595db33..a9713ed5380 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/kr/pretty v0.1.0 // indirect github.com/kr/text v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sirupsen/logrus v1.9.4 // indirect golang.org/x/net v0.49.0 // indirect golang.org/x/text v0.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index bf92be559ac..307310b7c69 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0C github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/weppos/publicsuffix-go v0.50.0 h1:M178k6l8cnh9T1c1cStkhytVxdk5zPd6gGZf8ySIuVo= diff --git a/x/crypto/cryptobyte/asn1.go b/x/crypto/cryptobyte/asn1.go index 446aa8110f0..f7ce533db1b 100644 --- a/x/crypto/cryptobyte/asn1.go +++ b/x/crypto/cryptobyte/asn1.go @@ -6,6 +6,7 @@ package cryptobyte import ( "fmt" + "log" "math/big" "reflect" "time" @@ -288,10 +289,18 @@ func (s *String) ReadASN1Integer(out interface{}) bool { return true case *big.Int: return s.readASN1BigInt(out) + case **big.Int: + bigInt := new(big.Int) + if !s.readASN1BigInt(bigInt) { + return false + } + *out = bigInt + return true case *[]byte: return s.readASN1Bytes(out) default: - panic("out does not point to an integer type") + log.Printf("unsupported type: %T (%#v)", out, out) + panic("out does not point to an integer type: " + reflect.TypeOf(out).Elem().String()) } } diff --git a/x/crypto/openpgp/packet/encrypted_key_test.go b/x/crypto/openpgp/packet/encrypted_key_test.go index 67eeb028a15..3585a93496b 100644 --- a/x/crypto/openpgp/packet/encrypted_key_test.go +++ b/x/crypto/openpgp/packet/encrypted_key_test.go @@ -25,7 +25,7 @@ func bigFromBase10(s string) *big.Int { } var encryptedKeyPub = rsa.PublicKey{ - E: 65537, + E: big.NewInt(65537), N: bigFromBase10("115804063926007623305902631768113868327816898845124614648849934718568541074358183759250136204762053879858102352159854352727097033322663029387610959884180306668628526686121021235757016368038585212410610742029286439607686208110250133174279811431933746643015923132833417396844716207301518956640020862630546868823"), } diff --git a/x/crypto/openpgp/packet/public_key.go b/x/crypto/openpgp/packet/public_key.go index dca8b1252d0..1d32057c8fc 100644 --- a/x/crypto/openpgp/packet/public_key.go +++ b/x/crypto/openpgp/packet/public_key.go @@ -102,8 +102,10 @@ func (f *ecdsaKey) byteLen() int { return 1 + len(f.oid) + 2 + len(f.p.bytes) } -type kdfHashFunction byte -type kdfAlgorithm byte +type ( + kdfHashFunction byte + kdfAlgorithm byte +) // ecdhKdf stores key derivation function parameters // used for ECDH encryption. See RFC 6637, Section 9. @@ -186,7 +188,7 @@ func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey { PubKeyAlgo: PubKeyAlgoRSA, PublicKey: pub, n: fromBig(pub.N), - e: fromBig(big.NewInt(int64(pub.E))), + e: fromBig(pub.E), } pk.setFingerPrintAndKeyId() @@ -329,11 +331,7 @@ func (pk *PublicKey) parseRSA(r io.Reader) (err error) { } rsa := &rsa.PublicKey{ N: new(big.Int).SetBytes(pk.n.bytes), - E: 0, - } - for i := 0; i < len(pk.e.bytes); i++ { - rsa.E <<= 8 - rsa.E |= int(pk.e.bytes[i]) + E: new(big.Int).SetBytes(pk.e.bytes), } pk.PublicKey = rsa return diff --git a/x/crypto/openpgp/packet/public_key_v3.go b/x/crypto/openpgp/packet/public_key_v3.go index 35541855a6d..523b5b33fd6 100644 --- a/x/crypto/openpgp/packet/public_key_v3.go +++ b/x/crypto/openpgp/packet/public_key_v3.go @@ -43,7 +43,7 @@ func newRSAPublicKeyV3(creationTime time.Time, pub *rsa.PublicKey) *PublicKeyV3 CreationTime: creationTime, PublicKey: pub, n: fromBig(pub.N), - e: fromBig(big.NewInt(int64(pub.E))), + e: fromBig(pub.E), } pk.setFingerPrintAndKeyId() @@ -82,7 +82,11 @@ func (pk *PublicKeyV3) setFingerPrintAndKeyId() { fingerPrint.Write(pk.n.bytes) fingerPrint.Write(pk.e.bytes) fingerPrint.Sum(pk.Fingerprint[:0]) - pk.KeyId = binary.BigEndian.Uint64(pk.n.bytes[len(pk.n.bytes)-8:]) + keyIDBytes := pk.n.bytes + if len(keyIDBytes) < 8 { + keyIDBytes = append(make([]byte, 8-len(keyIDBytes)), keyIDBytes...) + } + pk.KeyId = binary.BigEndian.Uint64(keyIDBytes[len(keyIDBytes)-8:]) } // parseRSA parses RSA public key material from the given Reader. See RFC 4880, @@ -95,19 +99,20 @@ func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) { return } - // RFC 4880 Section 12.2 requires the low 8 bytes of the - // modulus to form the key id. - if len(pk.n.bytes) < 8 { - return errors.StructuralError("v3 public key modulus is too short") - } - if len(pk.e.bytes) > 3 { - err = errors.UnsupportedError("large public exponent") - return - } - rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)} - for i := 0; i < len(pk.e.bytes); i++ { - rsa.E <<= 8 - rsa.E |= int(pk.e.bytes[i]) + /* + // RFC 4880 Section 12.2 requires the low 8 bytes of the + // modulus to form the key id. + if len(pk.n.bytes) < 8 { + return errors.StructuralError("v3 public key modulus is too short") + } + if len(pk.e.bytes) > 3 { + err = errors.UnsupportedError("large public exponent") + return + } + */ + rsa := &rsa.PublicKey{ + N: new(big.Int).SetBytes(pk.n.bytes), + E: new(big.Int).SetBytes(pk.e.bytes), } pk.PublicKey = rsa return diff --git a/x/crypto/ssh/agent/client.go b/x/crypto/ssh/agent/client.go index eb18411cbd2..c70653afe7d 100644 --- a/x/crypto/ssh/agent/client.go +++ b/x/crypto/ssh/agent/client.go @@ -218,8 +218,10 @@ type constrainExtensionAgentMsg struct { } // See [PROTOCOL.agent], section 4.7 -const agentExtension = 27 -const agentExtensionFailure = 28 +const ( + agentExtension = 27 + agentExtensionFailure = 28 +) // ErrExtensionUnsupported indicates that an extension defined in // [PROTOCOL.agent] section 4.7 is unsupported by the agent. Specifically this @@ -545,7 +547,7 @@ func (c *client) insertKey(s interface{}, comment string, constraints []byte) er req = ssh.Marshal(rsaKeyMsg{ Type: ssh.KeyAlgoRSA, N: k.N, - E: big.NewInt(int64(k.E)), + E: new(big.Int).Set(k.E), D: k.D, Iqmp: k.Precomputed.Qinv, P: k.Primes[0], diff --git a/x/crypto/ssh/agent/server.go b/x/crypto/ssh/agent/server.go index 874ea18f028..9f3652d990b 100644 --- a/x/crypto/ssh/agent/server.go +++ b/x/crypto/ssh/agent/server.go @@ -247,7 +247,7 @@ func parseRSAKey(req []byte) (*AddedKey, error) { } priv := &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ - E: int(k.E.Int64()), + E: k.E, N: k.N, }, D: k.D, @@ -396,7 +396,7 @@ func parseRSACert(req []byte) (*AddedKey, error) { priv := rsa.PrivateKey{ PublicKey: rsa.PublicKey{ - E: int(rsaPub.E.Int64()), + E: rsaPub.E, N: rsaPub.N, }, D: k.D, diff --git a/x/crypto/ssh/keys.go b/x/crypto/ssh/keys.go index f6d777e009a..f558cb14c58 100644 --- a/x/crypto/ssh/keys.go +++ b/x/crypto/ssh/keys.go @@ -458,13 +458,13 @@ func parseRSA(in []byte) (out PublicKey, rest []byte, err error) { } var key rsa.PublicKey - key.E = int(e) + key.E = w.E key.N = w.N return (*rsaPublicKey)(&key), w.Rest, nil } func (r *rsaPublicKey) Marshal() []byte { - e := new(big.Int).SetInt64(int64(r.E)) + e := new(big.Int).Set(r.E) // RSA publickey struct layout should match the struct used by // parseRSACert in the x/crypto/ssh/agent package. wirekey := struct { @@ -472,9 +472,9 @@ func (r *rsaPublicKey) Marshal() []byte { E *big.Int N *big.Int }{ - KeyAlgoRSA, - e, - r.N, + Name: KeyAlgoRSA, + E: e, + N: r.N, } return Marshal(&wirekey) } @@ -1441,8 +1441,10 @@ func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc { const privateKeyAuthMagic = "openssh-key-v1\x00" -type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error) -type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error) +type ( + openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error) + openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error) +) type openSSHEncryptedPrivateKey struct { CipherName string @@ -1540,7 +1542,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv pk := &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ N: key.N, - E: int(key.E.Int64()), + E: key.E, }, D: key.D, Primes: []*big.Int{key.P, key.Q}, @@ -1640,7 +1642,7 @@ func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt ope switch k := key.(type) { case *rsa.PrivateKey: - E := new(big.Int).SetInt64(int64(k.PublicKey.E)) + E := k.PublicKey.E // Marshal public key: // E and N are in reversed order in the public and private key. pubKey := struct { From 15a50077d50427e59f517c2e318f78176eddf0c0 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Wed, 28 Jan 2026 00:29:21 -0600 Subject: [PATCH 2/3] add PrefixToString and test --- crypto/x509/parser.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crypto/x509/parser.go b/crypto/x509/parser.go index 6de9909c448..05b457e9e76 100644 --- a/crypto/x509/parser.go +++ b/crypto/x509/parser.go @@ -25,7 +25,6 @@ import ( "github.com/runZeroInc/excrypto/crypto/sha256" "github.com/runZeroInc/excrypto/crypto/x509/pkix" "github.com/runZeroInc/excrypto/encoding/asn1" - "github.com/runZeroInc/excrypto/internal/godebug" "github.com/runZeroInc/excrypto/x/crypto/cryptobyte" cryptobyte_asn1 "github.com/runZeroInc/excrypto/x/crypto/cryptobyte/asn1" @@ -1078,7 +1077,8 @@ func processExtensions(out *Certificate) error { return nil } -var x509negativeserial = godebug.New("x509negativeserial") +/// zcrypto: always allow negative serials for compatibility +// var x509negativeserial = godebug.New("x509negativeserial") func parseCertificate(in *certificate) (*Certificate, error) { var err error @@ -1335,10 +1335,6 @@ func parseCertificate(in *certificate) (*Certificate, error) { } // ParseCertificate parses a single certificate from the given ASN.1 DER data. -// -// Before Go 1.23, ParseCertificate accepted certificates with negative serial -// numbers. This behavior can be restored by including "x509negativeserial=1" in -// the GODEBUG environment variable. func ParseCertificate(der []byte) (*Certificate, error) { var cert certificate rest, err := asn1.Unmarshal(der, &cert) From a3be732e19d00da23cba39c9fd9c2bd845de0dc5 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sat, 31 Jan 2026 17:22:32 -0600 Subject: [PATCH 3/3] bump deps/cleanup --- go.mod | 2 +- go.sum | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/go.mod b/go.mod index a9713ed5380..4a2d5d1b507 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.24.0 require ( github.com/google/go-cmp v0.7.0 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 + github.com/sirupsen/logrus v1.9.4 github.com/stretchr/testify v1.11.1 github.com/weppos/publicsuffix-go v0.50.2 golang.org/x/crypto v0.47.0 @@ -18,7 +19,6 @@ require ( github.com/kr/pretty v0.1.0 // indirect github.com/kr/text v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/sirupsen/logrus v1.9.4 // indirect golang.org/x/net v0.49.0 // indirect golang.org/x/text v0.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 307310b7c69..a6b4d3d4eb0 100644 --- a/go.sum +++ b/go.sum @@ -15,28 +15,16 @@ github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/weppos/publicsuffix-go v0.50.0 h1:M178k6l8cnh9T1c1cStkhytVxdk5zPd6gGZf8ySIuVo= -github.com/weppos/publicsuffix-go v0.50.0/go.mod h1:VXhClBYMlDrUsome4pOTpe68Ui0p6iQRAbyHQD1yKoU= github.com/weppos/publicsuffix-go v0.50.2 h1:KsJFc8IEKTJovM46SRCnGNsM+rFShxcs6VEHjOJcXzE= github.com/weppos/publicsuffix-go v0.50.2/go.mod h1:CbQCKDtXF8UcT7hrxeMa0MDjwhpOI9iYOU7cfq+yo8k= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=