OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/gnu-dev/fsf-gcc-snapshot-1-mar-12/or1k-gcc/libgo/go/crypto
    from Rev 747 to Rev 783
    Reverse comparison

Rev 747 → Rev 783

/ecdsa/ecdsa_test.go
0,0 → 1,227
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package ecdsa
 
import (
"crypto/elliptic"
"crypto/rand"
"crypto/sha1"
"encoding/hex"
"math/big"
"testing"
)
 
func testKeyGeneration(t *testing.T, c elliptic.Curve, tag string) {
priv, err := GenerateKey(c, rand.Reader)
if err != nil {
t.Errorf("%s: error: %s", tag, err)
return
}
if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
t.Errorf("%s: public key invalid: %s", tag, err)
}
}
 
func TestKeyGeneration(t *testing.T) {
testKeyGeneration(t, elliptic.P224(), "p224")
if testing.Short() {
return
}
testKeyGeneration(t, elliptic.P256(), "p256")
testKeyGeneration(t, elliptic.P384(), "p384")
testKeyGeneration(t, elliptic.P521(), "p521")
}
 
func testSignAndVerify(t *testing.T, c elliptic.Curve, tag string) {
priv, _ := GenerateKey(c, rand.Reader)
 
hashed := []byte("testing")
r, s, err := Sign(rand.Reader, priv, hashed)
if err != nil {
t.Errorf("%s: error signing: %s", tag, err)
return
}
 
if !Verify(&priv.PublicKey, hashed, r, s) {
t.Errorf("%s: Verify failed", tag)
}
 
hashed[0] ^= 0xff
if Verify(&priv.PublicKey, hashed, r, s) {
t.Errorf("%s: Verify always works!", tag)
}
}
 
func TestSignAndVerify(t *testing.T) {
testSignAndVerify(t, elliptic.P224(), "p224")
if testing.Short() {
return
}
testSignAndVerify(t, elliptic.P256(), "p256")
testSignAndVerify(t, elliptic.P384(), "p384")
testSignAndVerify(t, elliptic.P521(), "p521")
}
 
func fromHex(s string) *big.Int {
r, ok := new(big.Int).SetString(s, 16)
if !ok {
panic("bad hex")
}
return r
}
 
// These test vectors were taken from
// http://csrc.nist.gov/groups/STM/cavp/documents/dss/ecdsatestvectors.zip
var testVectors = []struct {
msg string
Qx, Qy string
r, s string
ok bool
}{
{
"09626b45493672e48f3d1226a3aff3201960e577d33a7f72c7eb055302db8fe8ed61685dd036b554942a5737cd1512cdf811ee0c00e6dd2f08c69f08643be396e85dafda664801e772cdb7396868ac47b172245b41986aa2648cb77fbbfa562581be06651355a0c4b090f9d17d8f0ab6cced4e0c9d386cf465a516630f0231bd",
"9504b5b82d97a264d8b3735e0568decabc4b6ca275bc53cbadfc1c40",
"03426f80e477603b10dee670939623e3da91a94267fc4e51726009ed",
"81d3ac609f9575d742028dd496450a58a60eea2dcf8b9842994916e1",
"96a8c5f382c992e8f30ccce9af120b067ec1d74678fa8445232f75a5",
false,
},
{
"96b2b6536f6df29be8567a72528aceeaccbaa66c66c534f3868ca9778b02faadb182e4ed34662e73b9d52ecbe9dc8e875fc05033c493108b380689ebf47e5b062e6a0cdb3dd34ce5fe347d92768d72f7b9b377c20aea927043b509c078ed2467d7113405d2ddd458811e6faf41c403a2a239240180f1430a6f4330df5d77de37",
"851e3100368a22478a0029353045ae40d1d8202ef4d6533cfdddafd8",
"205302ac69457dd345e86465afa72ee8c74ca97e2b0b999aec1f10c2",
"4450c2d38b697e990721aa2dbb56578d32b4f5aeb3b9072baa955ee0",
"e26d4b589166f7b4ba4b1c8fce823fa47aad22f8c9c396b8c6526e12",
false,
},
{
"86778dbb4a068a01047a8d245d632f636c11d2ad350740b36fad90428b454ad0f120cb558d12ea5c8a23db595d87543d06d1ef489263d01ee529871eb68737efdb8ff85bc7787b61514bed85b7e01d6be209e0a4eb0db5c8df58a5c5bf706d76cb2bdf7800208639e05b89517155d11688236e6a47ed37d8e5a2b1e0adea338e",
"ad5bda09d319a717c1721acd6688d17020b31b47eef1edea57ceeffc",
"c8ce98e181770a7c9418c73c63d01494b8b80a41098c5ea50692c984",
"de5558c257ab4134e52c19d8db3b224a1899cbd08cc508ce8721d5e9",
"745db7af5a477e5046705c0a5eff1f52cb94a79d481f0c5a5e108ecd",
true,
},
{
"4bc6ef1958556686dab1e39c3700054a304cbd8f5928603dcd97fafd1f29e69394679b638f71c9344ce6a535d104803d22119f57b5f9477e253817a52afa9bfbc9811d6cc8c8be6b6566c6ef48b439bbb532abe30627548c598867f3861ba0b154dc1c3deca06eb28df8efd28258554b5179883a36fbb1eecf4f93ee19d41e3d",
"cc5eea2edf964018bdc0504a3793e4d2145142caa09a72ac5fb8d3e8",
"a48d78ae5d08aa725342773975a00d4219cf7a8029bb8cf3c17c374a",
"67b861344b4e416d4094472faf4272f6d54a497177fbc5f9ef292836",
"1d54f3fcdad795bf3b23408ecbac3e1321d1d66f2e4e3d05f41f7020",
false,
},
{
"bb658732acbf3147729959eb7318a2058308b2739ec58907dd5b11cfa3ecf69a1752b7b7d806fe00ec402d18f96039f0b78dbb90a59c4414fb33f1f4e02e4089de4122cd93df5263a95be4d7084e2126493892816e6a5b4ed123cb705bf930c8f67af0fb4514d5769232a9b008a803af225160ce63f675bd4872c4c97b146e5e",
"6234c936e27bf141fc7534bfc0a7eedc657f91308203f1dcbd642855",
"27983d87ca785ef4892c3591ef4a944b1deb125dd58bd351034a6f84",
"e94e05b42d01d0b965ffdd6c3a97a36a771e8ea71003de76c4ecb13f",
"1dc6464ffeefbd7872a081a5926e9fc3e66d123f1784340ba17737e9",
false,
},
{
"7c00be9123bfa2c4290be1d8bc2942c7f897d9a5b7917e3aabd97ef1aab890f148400a89abd554d19bec9d8ed911ce57b22fbcf6d30ca2115f13ce0a3f569a23bad39ee645f624c49c60dcfc11e7d2be24de9c905596d8f23624d63dc46591d1f740e46f982bfae453f107e80db23545782be23ce43708245896fc54e1ee5c43",
"9f3f037282aaf14d4772edffff331bbdda845c3f65780498cde334f1",
"8308ee5a16e3bcb721b6bc30000a0419bc1aaedd761be7f658334066",
"6381d7804a8808e3c17901e4d283b89449096a8fba993388fa11dc54",
"8e858f6b5b253686a86b757bad23658cda53115ac565abca4e3d9f57",
false,
},
{
"cffc122a44840dc705bb37130069921be313d8bde0b66201aebc48add028ca131914ef2e705d6bedd19dc6cf9459bbb0f27cdfe3c50483808ffcdaffbeaa5f062e097180f07a40ef4ab6ed03fe07ed6bcfb8afeb42c97eafa2e8a8df469de07317c5e1494c41547478eff4d8c7d9f0f484ad90fedf6e1c35ee68fa73f1691601",
"a03b88a10d930002c7b17ca6af2fd3e88fa000edf787dc594f8d4fd4",
"e0cf7acd6ddc758e64847fe4df9915ebda2f67cdd5ec979aa57421f5",
"387b84dcf37dc343c7d2c5beb82f0bf8bd894b395a7b894565d296c1",
"4adc12ce7d20a89ce3925e10491c731b15ddb3f339610857a21b53b4",
false,
},
{
"26e0e0cafd85b43d16255908ccfd1f061c680df75aba3081246b337495783052ba06c60f4a486c1591a4048bae11b4d7fec4f161d80bdc9a7b79d23e44433ed625eab280521a37f23dd3e1bdc5c6a6cfaa026f3c45cf703e76dab57add93fe844dd4cda67dc3bddd01f9152579e49df60969b10f09ce9372fdd806b0c7301866",
"9a8983c42f2b5a87c37a00458b5970320d247f0c8a88536440173f7d",
"15e489ec6355351361900299088cfe8359f04fe0cab78dde952be80c",
"929a21baa173d438ec9f28d6a585a2f9abcfc0a4300898668e476dc0",
"59a853f046da8318de77ff43f26fe95a92ee296fa3f7e56ce086c872",
true,
},
{
"1078eac124f48ae4f807e946971d0de3db3748dd349b14cca5c942560fb25401b2252744f18ad5e455d2d97ed5ae745f55ff509c6c8e64606afe17809affa855c4c4cdcaf6b69ab4846aa5624ed0687541aee6f2224d929685736c6a23906d974d3c257abce1a3fb8db5951b89ecb0cda92b5207d93f6618fd0f893c32cf6a6e",
"d6e55820bb62c2be97650302d59d667a411956138306bd566e5c3c2b",
"631ab0d64eaf28a71b9cbd27a7a88682a2167cee6251c44e3810894f",
"65af72bc7721eb71c2298a0eb4eed3cec96a737cc49125706308b129",
"bd5a987c78e2d51598dbd9c34a9035b0069c580edefdacee17ad892a",
false,
},
{
"919deb1fdd831c23481dfdb2475dcbe325b04c34f82561ced3d2df0b3d749b36e255c4928973769d46de8b95f162b53cd666cad9ae145e7fcfba97919f703d864efc11eac5f260a5d920d780c52899e5d76f8fe66936ff82130761231f536e6a3d59792f784902c469aa897aabf9a0678f93446610d56d5e0981e4c8a563556b",
"269b455b1024eb92d860a420f143ac1286b8cce43031562ae7664574",
"baeb6ca274a77c44a0247e5eb12ca72bdd9a698b3f3ae69c9f1aaa57",
"cb4ec2160f04613eb0dfe4608486091a25eb12aa4dec1afe91cfb008",
"40b01d8cd06589481574f958b98ca08ade9d2a8fe31024375c01bb40",
false,
},
{
"6e012361250dacf6166d2dd1aa7be544c3206a9d43464b3fcd90f3f8cf48d08ec099b59ba6fe7d9bdcfaf244120aed1695d8be32d1b1cd6f143982ab945d635fb48a7c76831c0460851a3d62b7209c30cd9c2abdbe3d2a5282a9fcde1a6f418dd23c409bc351896b9b34d7d3a1a63bbaf3d677e612d4a80fa14829386a64b33f",
"6d2d695efc6b43b13c14111f2109608f1020e3e03b5e21cfdbc82fcd",
"26a4859296b7e360b69cf40be7bd97ceaffa3d07743c8489fc47ca1b",
"9a8cb5f2fdc288b7183c5b32d8e546fc2ed1ca4285eeae00c8b572ad",
"8c623f357b5d0057b10cdb1a1593dab57cda7bdec9cf868157a79b97",
true,
},
{
"bf6bd7356a52b234fe24d25557200971fc803836f6fec3cade9642b13a8e7af10ab48b749de76aada9d8927f9b12f75a2c383ca7358e2566c4bb4f156fce1fd4e87ef8c8d2b6b1bdd351460feb22cdca0437ac10ca5e0abbbce9834483af20e4835386f8b1c96daaa41554ceee56730aac04f23a5c765812efa746051f396566",
"14250131b2599939cf2d6bc491be80ddfe7ad9de644387ee67de2d40",
"b5dc473b5d014cd504022043c475d3f93c319a8bdcb7262d9e741803",
"4f21642f2201278a95339a80f75cc91f8321fcb3c9462562f6cbf145",
"452a5f816ea1f75dee4fd514fa91a0d6a43622981966c59a1b371ff8",
false,
},
{
"0eb7f4032f90f0bd3cf9473d6d9525d264d14c031a10acd31a053443ed5fe919d5ac35e0be77813071b4062f0b5fdf58ad5f637b76b0b305aec18f82441b6e607b44cdf6e0e3c7c57f24e6fd565e39430af4a6b1d979821ed0175fa03e3125506847654d7e1ae904ce1190ae38dc5919e257bdac2db142a6e7cd4da6c2e83770",
"d1f342b7790a1667370a1840255ac5bbbdc66f0bc00ae977d99260ac",
"76416cabae2de9a1000b4646338b774baabfa3db4673790771220cdb",
"bc85e3fc143d19a7271b2f9e1c04b86146073f3fab4dda1c3b1f35ca",
"9a5c70ede3c48d5f43307a0c2a4871934424a3303b815df4bb0f128e",
false,
},
{
"5cc25348a05d85e56d4b03cec450128727bc537c66ec3a9fb613c151033b5e86878632249cba83adcefc6c1e35dcd31702929c3b57871cda5c18d1cf8f9650a25b917efaed56032e43b6fc398509f0d2997306d8f26675f3a8683b79ce17128e006aa0903b39eeb2f1001be65de0520115e6f919de902b32c38d691a69c58c92",
"7e49a7abf16a792e4c7bbc4d251820a2abd22d9f2fc252a7bf59c9a6",
"44236a8fb4791c228c26637c28ae59503a2f450d4cfb0dc42aa843b9",
"084461b4050285a1a85b2113be76a17878d849e6bc489f4d84f15cd8",
"079b5bddcc4d45de8dbdfd39f69817c7e5afa454a894d03ee1eaaac3",
false,
},
{
"1951533ce33afb58935e39e363d8497a8dd0442018fd96dff167b3b23d7206a3ee182a3194765df4768a3284e23b8696c199b4686e670d60c9d782f08794a4bccc05cffffbd1a12acd9eb1cfa01f7ebe124da66ecff4599ea7720c3be4bb7285daa1a86ebf53b042bd23208d468c1b3aa87381f8e1ad63e2b4c2ba5efcf05845",
"31945d12ebaf4d81f02be2b1768ed80784bf35cf5e2ff53438c11493",
"a62bebffac987e3b9d3ec451eb64c462cdf7b4aa0b1bbb131ceaa0a4",
"bc3c32b19e42b710bca5c6aaa128564da3ddb2726b25f33603d2af3c",
"ed1a719cc0c507edc5239d76fe50e2306c145ad252bd481da04180c0",
false,
},
}
 
func TestVectors(t *testing.T) {
sha := sha1.New()
 
for i, test := range testVectors {
pub := PublicKey{
Curve: elliptic.P224(),
X: fromHex(test.Qx),
Y: fromHex(test.Qy),
}
msg, _ := hex.DecodeString(test.msg)
sha.Reset()
sha.Write(msg)
hashed := sha.Sum(nil)
r := fromHex(test.r)
s := fromHex(test.s)
if Verify(&pub, hashed, r, s) != test.ok {
t.Errorf("%d: bad result", i)
}
if testing.Short() {
break
}
}
}
/ecdsa/ecdsa.go
0,0 → 1,151
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
// defined in FIPS 186-3.
package ecdsa
 
// References:
// [NSA]: Suite B implementor's guide to FIPS 186-3,
// http://www.nsa.gov/ia/_files/ecdsa.pdf
// [SECG]: SECG, SEC1
// http://www.secg.org/download/aid-780/sec1-v2.pdf
 
import (
"crypto/elliptic"
"io"
"math/big"
)
 
// PublicKey represents an ECDSA public key.
type PublicKey struct {
elliptic.Curve
X, Y *big.Int
}
 
// PrivateKey represents a ECDSA private key.
type PrivateKey struct {
PublicKey
D *big.Int
}
 
var one = new(big.Int).SetInt64(1)
 
// randFieldElement returns a random element of the field underlying the given
// curve using the procedure given in [NSA] A.2.1.
func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
params := c.Params()
b := make([]byte, params.BitSize/8+8)
_, err = io.ReadFull(rand, b)
if err != nil {
return
}
 
k = new(big.Int).SetBytes(b)
n := new(big.Int).Sub(params.N, one)
k.Mod(k, n)
k.Add(k, one)
return
}
 
// GenerateKey generates a public&private key pair.
func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) {
k, err := randFieldElement(c, rand)
if err != nil {
return
}
 
priv = new(PrivateKey)
priv.PublicKey.Curve = c
priv.D = k
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
return
}
 
// hashToInt converts a hash value to an integer. There is some disagreement
// about how this is done. [NSA] suggests that this is done in the obvious
// manner, but [SECG] truncates the hash to the bit-length of the curve order
// first. We follow [SECG] because that's what OpenSSL does.
func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
orderBits := c.Params().N.BitLen()
orderBytes := (orderBits + 7) / 8
if len(hash) > orderBytes {
hash = hash[:orderBytes]
}
 
ret := new(big.Int).SetBytes(hash)
excess := orderBytes*8 - orderBits
if excess > 0 {
ret.Rsh(ret, uint(excess))
}
return ret
}
 
// Sign signs an arbitrary length hash (which should be the result of hashing a
// larger message) using the private key, priv. It returns the signature as a
// pair of integers. The security of the private key depends on the entropy of
// rand.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
// See [NSA] 3.4.1
c := priv.PublicKey.Curve
N := c.Params().N
 
var k, kInv *big.Int
for {
for {
k, err = randFieldElement(c, rand)
if err != nil {
r = nil
return
}
 
kInv = new(big.Int).ModInverse(k, N)
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
r.Mod(r, N)
if r.Sign() != 0 {
break
}
}
 
e := hashToInt(hash, c)
s = new(big.Int).Mul(priv.D, r)
s.Add(s, e)
s.Mul(s, kInv)
s.Mod(s, N)
if s.Sign() != 0 {
break
}
}
 
return
}
 
// Verify verifies the signature in r, s of hash using the public key, pub. It
// returns true iff the signature is valid.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
// See [NSA] 3.4.2
c := pub.Curve
N := c.Params().N
 
if r.Sign() == 0 || s.Sign() == 0 {
return false
}
if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
return false
}
e := hashToInt(hash, c)
w := new(big.Int).ModInverse(s, N)
 
u1 := e.Mul(e, w)
u2 := w.Mul(r, w)
 
x1, y1 := c.ScalarBaseMult(u1.Bytes())
x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
if x1.Cmp(x2) == 0 {
return false
}
x, _ := c.Add(x1, y1, x2, y2)
x.Mod(x, N)
return x.Cmp(r) == 0
}
/crypto.go
0,0 → 1,81
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package crypto collects common cryptographic constants.
package crypto
 
import (
"hash"
)
 
// Hash identifies a cryptographic hash function that is implemented in another
// package.
type Hash uint
 
const (
MD4 Hash = 1 + iota // import code.google.com/p/go.crypto/md4
MD5 // import crypto/md5
SHA1 // import crypto/sha1
SHA224 // import crypto/sha256
SHA256 // import crypto/sha256
SHA384 // import crypto/sha512
SHA512 // import crypto/sha512
MD5SHA1 // no implementation; MD5+SHA1 used for TLS RSA
RIPEMD160 // import code.google.com/p/go.crypto/ripemd160
maxHash
)
 
var digestSizes = []uint8{
MD4: 16,
MD5: 16,
SHA1: 20,
SHA224: 28,
SHA256: 32,
SHA384: 48,
SHA512: 64,
MD5SHA1: 36,
RIPEMD160: 20,
}
 
// Size returns the length, in bytes, of a digest resulting from the given hash
// function. It doesn't require that the hash function in question be linked
// into the program.
func (h Hash) Size() int {
if h > 0 && h < maxHash {
return int(digestSizes[h])
}
panic("crypto: Size of unknown hash function")
}
 
var hashes = make([]func() hash.Hash, maxHash)
 
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
 
// Available reports whether the given hash function is linked into the binary.
func (h Hash) Available() bool {
return h < maxHash && hashes[h] != nil
}
 
// RegisterHash registers a function that returns a new instance of the given
// hash function. This is intended to be called from the init function in
// packages that implement hash functions.
func RegisterHash(h Hash, f func() hash.Hash) {
if h >= maxHash {
panic("crypto: RegisterHash of unknown hash function")
}
hashes[h] = f
}
 
// PrivateKey represents a private key using an unspecified algorithm.
type PrivateKey interface{}
/rand/util.go
0,0 → 1,80
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package rand
 
import (
"errors"
"io"
"math/big"
)
 
// Prime returns a number, p, of the given size, such that p is prime
// with high probability.
func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
if bits < 1 {
err = errors.New("crypto/rand: prime size must be positive")
}
 
b := uint(bits % 8)
if b == 0 {
b = 8
}
 
bytes := make([]byte, (bits+7)/8)
p = new(big.Int)
 
for {
_, err = io.ReadFull(rand, bytes)
if err != nil {
return nil, err
}
 
// Clear bits in the first byte to make sure the candidate has a size <= bits.
bytes[0] &= uint8(int(1<<b) - 1)
// Don't let the value be too small, i.e, set the most significant bit.
bytes[0] |= 1 << (b - 1)
// Make the value odd since an even number this large certainly isn't prime.
bytes[len(bytes)-1] |= 1
 
p.SetBytes(bytes)
if p.ProbablyPrime(20) {
return
}
}
 
return
}
 
// Int returns a uniform random value in [0, max).
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
k := (max.BitLen() + 7) / 8
 
// b is the number of bits in the most significant byte of max.
b := uint(max.BitLen() % 8)
if b == 0 {
b = 8
}
 
bytes := make([]byte, k)
n = new(big.Int)
 
for {
_, err = io.ReadFull(rand, bytes)
if err != nil {
return nil, err
}
 
// Clear bits in the first byte to increase the probability
// that the candidate is < max.
bytes[0] &= uint8(int(1<<b) - 1)
 
n.SetBytes(bytes)
if n.Cmp(max) < 0 {
return
}
}
 
return
}
/rand/rand_windows.go
0,0 → 1,43
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Windows cryptographically secure pseudorandom number
// generator.
 
package rand
 
import (
"os"
"sync"
"syscall"
)
 
// Implemented by using Windows CryptoAPI 2.0.
 
func init() { Reader = &rngReader{} }
 
// A rngReader satisfies reads by reading from the Windows CryptGenRandom API.
type rngReader struct {
prov syscall.Handle
mu sync.Mutex
}
 
func (r *rngReader) Read(b []byte) (n int, err error) {
r.mu.Lock()
if r.prov == 0 {
const provType = syscall.PROV_RSA_FULL
const flags = syscall.CRYPT_VERIFYCONTEXT | syscall.CRYPT_SILENT
err := syscall.CryptAcquireContext(&r.prov, nil, nil, provType, flags)
if err != nil {
r.mu.Unlock()
return 0, os.NewSyscallError("CryptAcquireContext", err)
}
}
r.mu.Unlock()
err = syscall.CryptGenRandom(r.prov, uint32(len(b)), &b[0])
if err != nil {
return 0, os.NewSyscallError("CryptGenRandom", err)
}
return len(b), nil
}
/rand/rand_test.go
0,0 → 1,31
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package rand
 
import (
"bytes"
"compress/flate"
"testing"
)
 
func TestRead(t *testing.T) {
var n int = 4e6
if testing.Short() {
n = 1e5
}
b := make([]byte, n)
n, err := Read(b)
if n != len(b) || err != nil {
t.Fatalf("Read(buf) = %d, %s", n, err)
}
 
var z bytes.Buffer
f := flate.NewWriter(&z, 5)
f.Write(b)
f.Close()
if z.Len() < len(b)*99/100 {
t.Fatalf("Compressed %d -> %d", len(b), z.Len())
}
}
/rand/rand.go
0,0 → 1,18
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package rand implements a cryptographically secure
// pseudorandom number generator.
package rand
 
import "io"
 
// Reader is a global, shared instance of a cryptographically
// strong pseudo-random generator.
// On Unix-like systems, Reader reads from /dev/urandom.
// On Windows systems, Reader uses the CryptGenRandom API.
var Reader io.Reader
 
// Read is a helper function that calls Reader.Read.
func Read(b []byte) (n int, err error) { return Reader.Read(b) }
/rand/rand_unix.go
0,0 → 1,127
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// +build darwin freebsd linux netbsd openbsd
 
// Unix cryptographically secure pseudorandom number
// generator.
 
package rand
 
import (
"bufio"
"crypto/aes"
"io"
"os"
"sync"
"time"
)
 
// Easy implementation: read from /dev/urandom.
// This is sufficient on Linux, OS X, and FreeBSD.
 
func init() { Reader = &devReader{name: "/dev/urandom"} }
 
// A devReader satisfies reads by reading the file named name.
type devReader struct {
name string
f io.Reader
mu sync.Mutex
}
 
func (r *devReader) Read(b []byte) (n int, err error) {
r.mu.Lock()
defer r.mu.Unlock()
if r.f == nil {
f, err := os.Open(r.name)
if f == nil {
return 0, err
}
r.f = bufio.NewReader(f)
}
return r.f.Read(b)
}
 
// Alternate pseudo-random implementation for use on
// systems without a reliable /dev/urandom. So far we
// haven't needed it.
 
// newReader returns a new pseudorandom generator that
// seeds itself by reading from entropy. If entropy == nil,
// the generator seeds itself by reading from the system's
// random number generator, typically /dev/random.
// The Read method on the returned reader always returns
// the full amount asked for, or else it returns an error.
//
// The generator uses the X9.31 algorithm with AES-128,
// reseeding after every 1 MB of generated data.
func newReader(entropy io.Reader) io.Reader {
if entropy == nil {
entropy = &devReader{name: "/dev/random"}
}
return &reader{entropy: entropy}
}
 
type reader struct {
mu sync.Mutex
budget int // number of bytes that can be generated
cipher *aes.Cipher
entropy io.Reader
time, seed, dst, key [aes.BlockSize]byte
}
 
func (r *reader) Read(b []byte) (n int, err error) {
r.mu.Lock()
defer r.mu.Unlock()
n = len(b)
 
for len(b) > 0 {
if r.budget == 0 {
_, err := io.ReadFull(r.entropy, r.seed[0:])
if err != nil {
return n - len(b), err
}
_, err = io.ReadFull(r.entropy, r.key[0:])
if err != nil {
return n - len(b), err
}
r.cipher, err = aes.NewCipher(r.key[0:])
if err != nil {
return n - len(b), err
}
r.budget = 1 << 20 // reseed after generating 1MB
}
r.budget -= aes.BlockSize
 
// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
//
// single block:
// t = encrypt(time)
// dst = encrypt(t^seed)
// seed = encrypt(t^dst)
ns := time.Now().UnixNano()
r.time[0] = byte(ns >> 56)
r.time[1] = byte(ns >> 48)
r.time[2] = byte(ns >> 40)
r.time[3] = byte(ns >> 32)
r.time[4] = byte(ns >> 24)
r.time[5] = byte(ns >> 16)
r.time[6] = byte(ns >> 8)
r.time[7] = byte(ns)
r.cipher.Encrypt(r.time[0:], r.time[0:])
for i := 0; i < aes.BlockSize; i++ {
r.dst[i] = r.time[i] ^ r.seed[i]
}
r.cipher.Encrypt(r.dst[0:], r.dst[0:])
for i := 0; i < aes.BlockSize; i++ {
r.seed[i] = r.time[i] ^ r.dst[i]
}
r.cipher.Encrypt(r.seed[0:], r.seed[0:])
 
m := copy(b, r.dst[0:])
b = b[m:]
}
 
return n, nil
}
/md5/md5block.go
0,0 → 1,172
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// MD5 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
 
package md5
 
// table[i] = int((1<<32) * abs(sin(i+1 radians))).
var table = []uint32{
// round 1
0xd76aa478,
0xe8c7b756,
0x242070db,
0xc1bdceee,
0xf57c0faf,
0x4787c62a,
0xa8304613,
0xfd469501,
0x698098d8,
0x8b44f7af,
0xffff5bb1,
0x895cd7be,
0x6b901122,
0xfd987193,
0xa679438e,
0x49b40821,
 
// round 2
0xf61e2562,
0xc040b340,
0x265e5a51,
0xe9b6c7aa,
0xd62f105d,
0x2441453,
0xd8a1e681,
0xe7d3fbc8,
0x21e1cde6,
0xc33707d6,
0xf4d50d87,
0x455a14ed,
0xa9e3e905,
0xfcefa3f8,
0x676f02d9,
0x8d2a4c8a,
 
// round3
0xfffa3942,
0x8771f681,
0x6d9d6122,
0xfde5380c,
0xa4beea44,
0x4bdecfa9,
0xf6bb4b60,
0xbebfbc70,
0x289b7ec6,
0xeaa127fa,
0xd4ef3085,
0x4881d05,
0xd9d4d039,
0xe6db99e5,
0x1fa27cf8,
0xc4ac5665,
 
// round 4
0xf4292244,
0x432aff97,
0xab9423a7,
0xfc93a039,
0x655b59c3,
0x8f0ccc92,
0xffeff47d,
0x85845dd1,
0x6fa87e4f,
0xfe2ce6e0,
0xa3014314,
0x4e0811a1,
0xf7537e82,
0xbd3af235,
0x2ad7d2bb,
0xeb86d391,
}
 
var shift1 = []uint{7, 12, 17, 22}
var shift2 = []uint{5, 9, 14, 20}
var shift3 = []uint{4, 11, 16, 23}
var shift4 = []uint{6, 10, 15, 21}
 
func _Block(dig *digest, p []byte) int {
a := dig.s[0]
b := dig.s[1]
c := dig.s[2]
d := dig.s[3]
n := 0
var X [16]uint32
for len(p) >= _Chunk {
aa, bb, cc, dd := a, b, c, d
 
j := 0
for i := 0; i < 16; i++ {
X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
j += 4
}
 
// If this needs to be made faster in the future,
// the usual trick is to unroll each of these
// loops by a factor of 4; that lets you replace
// the shift[] lookups with constants and,
// with suitable variable renaming in each
// unrolled body, delete the a, b, c, d = d, a, b, c
// (or you can let the optimizer do the renaming).
//
// The index variables are uint so that % by a power
// of two can be optimized easily by a compiler.
 
// Round 1.
for i := uint(0); i < 16; i++ {
x := i
s := shift1[i%4]
f := ((c ^ d) & b) ^ d
a += f + X[x] + table[i]
a = a<<s | a>>(32-s) + b
a, b, c, d = d, a, b, c
}
 
// Round 2.
for i := uint(0); i < 16; i++ {
x := (1 + 5*i) % 16
s := shift2[i%4]
g := ((b ^ c) & d) ^ c
a += g + X[x] + table[i+16]
a = a<<s | a>>(32-s) + b
a, b, c, d = d, a, b, c
}
 
// Round 3.
for i := uint(0); i < 16; i++ {
x := (5 + 3*i) % 16
s := shift3[i%4]
h := b ^ c ^ d
a += h + X[x] + table[i+32]
a = a<<s | a>>(32-s) + b
a, b, c, d = d, a, b, c
}
 
// Round 4.
for i := uint(0); i < 16; i++ {
x := (7 * i) % 16
s := shift4[i%4]
j := c ^ (b | ^d)
a += j + X[x] + table[i+48]
a = a<<s | a>>(32-s) + b
a, b, c, d = d, a, b, c
}
 
a += aa
b += bb
c += cc
d += dd
 
p = p[_Chunk:]
n += _Chunk
}
 
dig.s[0] = a
dig.s[1] = b
dig.s[2] = c
dig.s[3] = d
return n
}
/md5/md5_test.go
0,0 → 1,71
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package md5
 
import (
"fmt"
"io"
"testing"
)
 
type md5Test struct {
out string
in string
}
 
var golden = []md5Test{
{"d41d8cd98f00b204e9800998ecf8427e", ""},
{"0cc175b9c0f1b6a831c399e269772661", "a"},
{"187ef4436122d1cc2f40dc2b92f0eba0", "ab"},
{"900150983cd24fb0d6963f7d28e17f72", "abc"},
{"e2fc714c4727ee9395f324cd2e7f331f", "abcd"},
{"ab56b4d92b40713acc5af89985d4b786", "abcde"},
{"e80b5017098950fc58aad83c8c14978e", "abcdef"},
{"7ac66c0f148de9519b8bd264312c4d64", "abcdefg"},
{"e8dc4081b13434b45189a720b77b6818", "abcdefgh"},
{"8aa99b1f439ff71293e95357bac6fd94", "abcdefghi"},
{"a925576942e94b2ef57a066101b48876", "abcdefghij"},
{"d747fc1719c7eacb84058196cfe56d57", "Discard medicine more than two years old."},
{"bff2dcb37ef3a44ba43ab144768ca837", "He who has a shady past knows that nice guys finish last."},
{"0441015ecb54a7342d017ed1bcfdbea5", "I wouldn't marry him with a ten foot pole."},
{"9e3cac8e9e9757a60c3ea391130d3689", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
{"a0f04459b031f916a59a35cc482dc039", "The days of the digital watch are numbered. -Tom Stoppard"},
{"e7a48e0fe884faf31475d2a04b1362cc", "Nepal premier won't resign."},
{"637d2fe925c07c113800509964fb0e06", "For every action there is an equal and opposite government program."},
{"834a8d18d5c6562119cf4c7f5086cb71", "His money is twice tainted: 'taint yours and 'taint mine."},
{"de3a4d2fd6c73ec2db2abad23b444281", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
{"acf203f997e2cf74ea3aff86985aefaf", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
{"e1c1384cb4d2221dfdd7c795a4222c9a", "size: a.out: bad magic"},
{"c90f3ddecc54f34228c063d7525bf644", "The major problem is with sendmail. -Mark Horton"},
{"cdf7ab6c1fd49bd9933c43f3ea5af185", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
{"83bc85234942fc883c063cbd7f0ad5d0", "If the enemy is within range, then so are you."},
{"277cbe255686b48dd7e8f389394d9299", "It's well we cannot hear the screams/That we create in others' dreams."},
{"fd3fb0a7ffb8af16603f3d3af98f8e1f", "You remind me of a TV show, but that's all right: I watch it anyway."},
{"469b13a78ebf297ecda64d4723655154", "C is as portable as Stonehedge!!"},
{"63eb3a2f466410104731c4b037600110", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
{"72c2ed7592debca1c90fc0100f931a2f", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
{"132f7619d33b523b1d9e5bd8e0928355", "How can you write a big system without C++? -Paul Glick"},
}
 
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("md5[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
}
/md5/md5.go
0,0 → 1,119
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package md5 implements the MD5 hash algorithm as defined in RFC 1321.
package md5
 
import (
"crypto"
"hash"
)
 
func init() {
crypto.RegisterHash(crypto.MD5, New)
}
 
// The size of an MD5 checksum in bytes.
const Size = 16
 
// The blocksize of MD5 in bytes.
const BlockSize = 64
 
const (
_Chunk = 64
_Init0 = 0x67452301
_Init1 = 0xEFCDAB89
_Init2 = 0x98BADCFE
_Init3 = 0x10325476
)
 
// digest represents the partial evaluation of a checksum.
type digest struct {
s [4]uint32
x [_Chunk]byte
nx int
len uint64
}
 
func (d *digest) Reset() {
d.s[0] = _Init0
d.s[1] = _Init1
d.s[2] = _Init2
d.s[3] = _Init3
d.nx = 0
d.len = 0
}
 
// New returns a new hash.Hash computing the MD5 checksum.
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
 
func (d *digest) Size() int { return Size }
 
func (d *digest) BlockSize() int { return BlockSize }
 
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.len += uint64(nn)
if d.nx > 0 {
n := len(p)
if n > _Chunk-d.nx {
n = _Chunk - d.nx
}
for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i]
}
d.nx += n
if d.nx == _Chunk {
_Block(d, d.x[0:])
d.nx = 0
}
p = p[n:]
}
n := _Block(d, p)
p = p[n:]
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
 
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := *d0
 
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
tmp[0] = 0x80
if len%64 < 56 {
d.Write(tmp[0 : 56-len%64])
} else {
d.Write(tmp[0 : 64+56-len%64])
}
 
// Length in bits.
len <<= 3
for i := uint(0); i < 8; i++ {
tmp[i] = byte(len >> (8 * i))
}
d.Write(tmp[0:8])
 
if d.nx != 0 {
panic("d.nx != 0")
}
 
var digest [Size]byte
for i, s := range d.s {
digest[i*4] = byte(s)
digest[i*4+1] = byte(s >> 8)
digest[i*4+2] = byte(s >> 16)
digest[i*4+3] = byte(s >> 24)
}
 
return append(in, digest[:]...)
}
/rsa/pkcs1v15_test.go
0,0 → 1,221
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package rsa
 
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"io"
"math/big"
"testing"
"testing/quick"
)
 
func decodeBase64(in string) []byte {
out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
n, err := base64.StdEncoding.Decode(out, []byte(in))
if err != nil {
return nil
}
return out[0:n]
}
 
type DecryptPKCS1v15Test struct {
in, out string
}
 
// These test vectors were generated with `openssl rsautl -pkcs -encrypt`
var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{
{
"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
"x",
},
{
"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
"testing.",
},
{
"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
"testing.\n",
},
{
"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
"01234567890123456789012345678901234567890123456789012",
},
}
 
func TestDecryptPKCS1v15(t *testing.T) {
for i, test := range decryptPKCS1v15Tests {
out, err := DecryptPKCS1v15(nil, rsaPrivateKey, decodeBase64(test.in))
if err != nil {
t.Errorf("#%d error decrypting", i)
}
want := []byte(test.out)
if bytes.Compare(out, want) != 0 {
t.Errorf("#%d got:%#v want:%#v", i, out, want)
}
}
}
 
func TestEncryptPKCS1v15(t *testing.T) {
random := rand.Reader
k := (rsaPrivateKey.N.BitLen() + 7) / 8
 
tryEncryptDecrypt := func(in []byte, blind bool) bool {
if len(in) > k-11 {
in = in[0 : k-11]
}
 
ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in)
if err != nil {
t.Errorf("error encrypting: %s", err)
return false
}
 
var rand io.Reader
if !blind {
rand = nil
} else {
rand = random
}
plaintext, err := DecryptPKCS1v15(rand, rsaPrivateKey, ciphertext)
if err != nil {
t.Errorf("error decrypting: %s", err)
return false
}
 
if bytes.Compare(plaintext, in) != 0 {
t.Errorf("output mismatch: %#v %#v", plaintext, in)
return false
}
return true
}
 
config := new(quick.Config)
if testing.Short() {
config.MaxCount = 10
}
quick.Check(tryEncryptDecrypt, config)
}
 
// These test vectors were generated with `openssl rsautl -pkcs -encrypt`
var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{
{
"e6ukkae6Gykq0fKzYwULpZehX+UPXYzMoB5mHQUDEiclRbOTqas4Y0E6nwns1BBpdvEJcilhl5zsox/6DtGsYg==",
"1234",
},
{
"Dtis4uk/q/LQGGqGk97P59K03hkCIVFMEFZRgVWOAAhxgYpCRG0MX2adptt92l67IqMki6iVQyyt0TtX3IdtEw==",
"FAIL",
},
{
"LIyFyCYCptPxrvTxpol8F3M7ZivlMsf53zs0vHRAv+rDIh2YsHS69ePMoPMe3TkOMZ3NupiL3takPxIs1sK+dw==",
"abcd",
},
{
"bafnobel46bKy76JzqU/RIVOH0uAYvzUtauKmIidKgM0sMlvobYVAVQPeUQ/oTGjbIZ1v/6Gyi5AO4DtHruGdw==",
"FAIL",
},
}
 
func TestEncryptPKCS1v15SessionKey(t *testing.T) {
for i, test := range decryptPKCS1v15SessionKeyTests {
key := []byte("FAIL")
err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, decodeBase64(test.in), key)
if err != nil {
t.Errorf("#%d error decrypting", i)
}
want := []byte(test.out)
if bytes.Compare(key, want) != 0 {
t.Errorf("#%d got:%#v want:%#v", i, key, want)
}
}
}
 
func TestNonZeroRandomBytes(t *testing.T) {
random := rand.Reader
 
b := make([]byte, 512)
err := nonZeroRandomBytes(b, random)
if err != nil {
t.Errorf("returned error: %s", err)
}
for _, b := range b {
if b == 0 {
t.Errorf("Zero octet found")
return
}
}
}
 
type signPKCS1v15Test struct {
in, out string
}
 
// These vectors have been tested with
// `openssl rsautl -verify -inkey pk -in signature | hexdump -C`
var signPKCS1v15Tests = []signPKCS1v15Test{
{"Test.\n", "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e336ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"},
}
 
func TestSignPKCS1v15(t *testing.T) {
for i, test := range signPKCS1v15Tests {
h := sha1.New()
h.Write([]byte(test.in))
digest := h.Sum(nil)
 
s, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.SHA1, digest)
if err != nil {
t.Errorf("#%d %s", i, err)
}
 
expected, _ := hex.DecodeString(test.out)
if bytes.Compare(s, expected) != 0 {
t.Errorf("#%d got: %x want: %x", i, s, expected)
}
}
}
 
func TestVerifyPKCS1v15(t *testing.T) {
for i, test := range signPKCS1v15Tests {
h := sha1.New()
h.Write([]byte(test.in))
digest := h.Sum(nil)
 
sig, _ := hex.DecodeString(test.out)
 
err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, digest, sig)
if err != nil {
t.Errorf("#%d %s", i, err)
}
}
}
 
// In order to generate new test vectors you'll need the PEM form of this key:
// -----BEGIN RSA PRIVATE KEY-----
// MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
// fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
// /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
// RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
// EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
// IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
// tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
// -----END RSA PRIVATE KEY-----
 
var rsaPrivateKey = &PrivateKey{
PublicKey: PublicKey{
N: fromBase10("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"),
E: 65537,
},
D: fromBase10("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"),
Primes: []*big.Int{
fromBase10("98920366548084643601728869055592650835572950932266967461790948584315647051443"),
fromBase10("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
},
}
/rsa/pkcs1v15.go
0,0 → 1,242
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package rsa
 
import (
"crypto"
"crypto/subtle"
"errors"
"io"
"math/big"
)
 
// This file implements encryption and decryption using PKCS#1 v1.5 padding.
 
// EncryptPKCS1v15 encrypts the given message with RSA and the padding scheme from PKCS#1 v1.5.
// The message must be no longer than the length of the public modulus minus 11 bytes.
// WARNING: use of this function to encrypt plaintexts other than session keys
// is dangerous. Use RSA OAEP in new protocols.
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error) {
k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-11 {
err = MessageTooLongError{}
return
}
 
// EM = 0x02 || PS || 0x00 || M
em := make([]byte, k-1)
em[0] = 2
ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
err = nonZeroRandomBytes(ps, rand)
if err != nil {
return
}
em[len(em)-len(msg)-1] = 0
copy(mm, msg)
 
m := new(big.Int).SetBytes(em)
c := encrypt(new(big.Int), pub, m)
out = c.Bytes()
return
}
 
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error) {
valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
if err == nil && valid == 0 {
err = DecryptionError{}
}
 
return
}
 
// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
// It returns an error if the ciphertext is the wrong length or if the
// ciphertext is greater than the public modulus. Otherwise, no error is
// returned. If the padding is valid, the resulting plaintext message is copied
// into key. Otherwise, key is unchanged. These alternatives occur in constant
// time. It is intended that the user of this function generate a random
// session key beforehand and continue the protocol with the resulting value.
// This will remove any possibility that an attacker can learn any information
// about the plaintext.
// See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
// (Crypto '98).
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
k := (priv.N.BitLen() + 7) / 8
if k-(len(key)+3+8) < 0 {
err = DecryptionError{}
return
}
 
valid, msg, err := decryptPKCS1v15(rand, priv, ciphertext)
if err != nil {
return
}
 
valid &= subtle.ConstantTimeEq(int32(len(msg)), int32(len(key)))
subtle.ConstantTimeCopy(valid, key, msg)
return
}
 
func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, msg []byte, err error) {
k := (priv.N.BitLen() + 7) / 8
if k < 11 {
err = DecryptionError{}
return
}
 
c := new(big.Int).SetBytes(ciphertext)
m, err := decrypt(rand, priv, c)
if err != nil {
return
}
 
em := leftPad(m.Bytes(), k)
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
 
// The remainder of the plaintext must be a string of non-zero random
// octets, followed by a 0, followed by the message.
// lookingForIndex: 1 iff we are still looking for the zero.
// index: the offset of the first zero byte.
var lookingForIndex, index int
lookingForIndex = 1
 
for i := 2; i < len(em); i++ {
equals0 := subtle.ConstantTimeByteEq(em[i], 0)
index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
}
 
valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1)
msg = em[index+1:]
return
}
 
// nonZeroRandomBytes fills the given slice with non-zero random octets.
func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
_, err = io.ReadFull(rand, s)
if err != nil {
return
}
 
for i := 0; i < len(s); i++ {
for s[i] == 0 {
_, err = io.ReadFull(rand, s[i:i+1])
if err != nil {
return
}
// In tests, the PRNG may return all zeros so we do
// this to break the loop.
s[i] ^= 0x42
}
}
 
return
}
 
// These are ASN1 DER structures:
// DigestInfo ::= SEQUENCE {
// digestAlgorithm AlgorithmIdentifier,
// digest OCTET STRING
// }
// For performance, we don't use the generic ASN1 encoder. Rather, we
// precompute a prefix of the digest value that makes a valid ASN1 DER string
// with the correct contents.
var hashPrefixes = map[crypto.Hash][]byte{
crypto.MD5: {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
crypto.MD5SHA1: {}, // A special TLS case which doesn't use an ASN1 prefix.
crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
}
 
// SignPKCS1v15 calculates the signature of hashed using RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5.
// Note that hashed must be the result of hashing the input message using the
// given hash function.
func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) (s []byte, err error) {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
return
}
 
tLen := len(prefix) + hashLen
k := (priv.N.BitLen() + 7) / 8
if k < tLen+11 {
return nil, MessageTooLongError{}
}
 
// EM = 0x00 || 0x01 || PS || 0x00 || T
em := make([]byte, k)
em[1] = 1
for i := 2; i < k-tLen-1; i++ {
em[i] = 0xff
}
copy(em[k-tLen:k-hashLen], prefix)
copy(em[k-hashLen:k], hashed)
 
m := new(big.Int).SetBytes(em)
c, err := decrypt(rand, priv, m)
if err == nil {
s = c.Bytes()
}
return
}
 
// VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature.
// hashed is the result of hashing the input message using the given hash
// function and sig is the signature. A valid signature is indicated by
// returning a nil error.
func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (err error) {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
return
}
 
tLen := len(prefix) + hashLen
k := (pub.N.BitLen() + 7) / 8
if k < tLen+11 {
err = VerificationError{}
return
}
 
c := new(big.Int).SetBytes(sig)
m := encrypt(new(big.Int), pub, c)
em := leftPad(m.Bytes(), k)
// EM = 0x00 || 0x01 || PS || 0x00 || T
 
ok := subtle.ConstantTimeByteEq(em[0], 0)
ok &= subtle.ConstantTimeByteEq(em[1], 1)
ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
 
for i := 2; i < k-tLen-1; i++ {
ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
}
 
if ok != 1 {
return VerificationError{}
}
 
return nil
}
 
func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
hashLen = hash.Size()
if inLen != hashLen {
return 0, nil, errors.New("input must be hashed message")
}
prefix, ok := hashPrefixes[hash]
if !ok {
return 0, nil, errors.New("unsupported hash function")
}
return
}
/rsa/rsa_test.go
0,0 → 1,348
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package rsa
 
import (
"bytes"
"crypto/rand"
"crypto/sha1"
"math/big"
"testing"
)
 
func TestKeyGeneration(t *testing.T) {
size := 1024
if testing.Short() {
size = 128
}
priv, err := GenerateKey(rand.Reader, size)
if err != nil {
t.Errorf("failed to generate key")
}
testKeyBasics(t, priv)
}
 
func Test3PrimeKeyGeneration(t *testing.T) {
if testing.Short() {
return
}
 
size := 768
priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size)
if err != nil {
t.Errorf("failed to generate key")
}
testKeyBasics(t, priv)
}
 
func Test4PrimeKeyGeneration(t *testing.T) {
if testing.Short() {
return
}
 
size := 768
priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size)
if err != nil {
t.Errorf("failed to generate key")
}
testKeyBasics(t, priv)
}
 
func testKeyBasics(t *testing.T, priv *PrivateKey) {
if err := priv.Validate(); err != nil {
t.Errorf("Validate() failed: %s", err)
}
 
pub := &priv.PublicKey
m := big.NewInt(42)
c := encrypt(new(big.Int), pub, m)
 
m2, err := decrypt(nil, priv, c)
if err != nil {
t.Errorf("error while decrypting: %s", err)
return
}
if m.Cmp(m2) != 0 {
t.Errorf("got:%v, want:%v (%+v)", m2, m, priv)
}
 
m3, err := decrypt(rand.Reader, priv, c)
if err != nil {
t.Errorf("error while decrypting (blind): %s", err)
}
if m.Cmp(m3) != 0 {
t.Errorf("(blind) got:%v, want:%v (%#v)", m3, m, priv)
}
}
 
func fromBase10(base10 string) *big.Int {
i := new(big.Int)
i.SetString(base10, 10)
return i
}
 
func BenchmarkRSA2048Decrypt(b *testing.B) {
b.StopTimer()
priv := &PrivateKey{
PublicKey: PublicKey{
N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"),
E: 3,
},
D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"),
Primes: []*big.Int{
fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"),
fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"),
},
}
priv.Precompute()
 
c := fromBase10("1000")
 
b.StartTimer()
 
for i := 0; i < b.N; i++ {
decrypt(nil, priv, c)
}
}
 
func Benchmark3PrimeRSA2048Decrypt(b *testing.B) {
b.StopTimer()
priv := &PrivateKey{
PublicKey: PublicKey{
N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
E: 3,
},
D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"),
Primes: []*big.Int{
fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
},
}
priv.Precompute()
 
c := fromBase10("1000")
 
b.StartTimer()
 
for i := 0; i < b.N; i++ {
decrypt(nil, priv, c)
}
}
 
type testEncryptOAEPMessage struct {
in []byte
seed []byte
out []byte
}
 
type testEncryptOAEPStruct struct {
modulus string
e int
d string
msgs []testEncryptOAEPMessage
}
 
func TestEncryptOAEP(t *testing.T) {
sha1 := sha1.New()
n := new(big.Int)
for i, test := range testEncryptOAEPData {
n.SetString(test.modulus, 16)
public := PublicKey{n, test.e}
 
for j, message := range test.msgs {
randomSource := bytes.NewBuffer(message.seed)
out, err := EncryptOAEP(sha1, randomSource, &public, message.in, nil)
if err != nil {
t.Errorf("#%d,%d error: %s", i, j, err)
}
if bytes.Compare(out, message.out) != 0 {
t.Errorf("#%d,%d bad result: %x (want %x)", i, j, out, message.out)
}
}
}
}
 
func TestDecryptOAEP(t *testing.T) {
random := rand.Reader
 
sha1 := sha1.New()
n := new(big.Int)
d := new(big.Int)
for i, test := range testEncryptOAEPData {
n.SetString(test.modulus, 16)
d.SetString(test.d, 16)
private := new(PrivateKey)
private.PublicKey = PublicKey{n, test.e}
private.D = d
 
for j, message := range test.msgs {
out, err := DecryptOAEP(sha1, nil, private, message.out, nil)
if err != nil {
t.Errorf("#%d,%d error: %s", i, j, err)
} else if bytes.Compare(out, message.in) != 0 {
t.Errorf("#%d,%d bad result: %#v (want %#v)", i, j, out, message.in)
}
 
// Decrypt with blinding.
out, err = DecryptOAEP(sha1, random, private, message.out, nil)
if err != nil {
t.Errorf("#%d,%d (blind) error: %s", i, j, err)
} else if bytes.Compare(out, message.in) != 0 {
t.Errorf("#%d,%d (blind) bad result: %#v (want %#v)", i, j, out, message.in)
}
}
if testing.Short() {
break
}
}
}
 
// testEncryptOAEPData contains a subset of the vectors from RSA's "Test vectors for RSA-OAEP".
var testEncryptOAEPData = []testEncryptOAEPStruct{
// Key 1
{"a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb",
65537,
"53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1",
[]testEncryptOAEPMessage{
// Example 1.1
{
[]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,
0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1, 0xdd,
0xa0, 0xa5, 0xef,
},
[]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,
0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f,
0x8a, 0xfc, 0xc2, 0x01, 0x03, 0x5f, 0x7b, 0x6d, 0x8e,
0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a,
0x53, 0x5f, 0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f,
0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22,
0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70,
0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26, 0xd9, 0x8c,
0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94,
0xa0, 0xd9, 0xfa, 0x1e, 0x8c, 0x40, 0x24, 0x30, 0x9c,
0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a,
0xc7, 0x2e, 0x8a,
},
},
// Example 1.2
{
[]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,
0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25, 0xfe,
0x4f, 0xe3, 0x5f,
},
[]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,
0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a,
0x29, 0x93, 0x2e, 0x3f, 0x00, 0xc8, 0x15, 0x15, 0x23,
0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf,
0x43, 0x52, 0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58,
0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52,
0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6,
0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b, 0xbb, 0xe6,
0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39,
0x5a, 0x35, 0x2d, 0x5e, 0xd1, 0x15, 0x91, 0x2d, 0xf6,
0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71,
0x49, 0x2b, 0x44,
},
},
// Example 1.3
{
[]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,
0xa6, 0x42, 0x3e, 0xb0, 0xe1, 0xd0, 0x2d, 0x4f, 0xe6,
0x46, 0xcf, 0x69, 0x9d, 0xfd, 0x81, 0x8c, 0x6e, 0x97,
0xb0, 0x51,
},
[]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,
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,
0x32, 0x2d, 0x60, 0x2d, 0x2e, 0x62, 0x5e, 0x95, 0xeb,
0x81, 0xb2, 0xf1, 0xc9, 0x72, 0x4e, 0x82, 0x2e, 0xca,
0x76, 0xdb, 0x86, 0x18, 0xcf, 0x09, 0xc5, 0x34, 0x35,
0x03, 0xa4, 0x36, 0x08, 0x35, 0xb5, 0x90, 0x3b, 0xc6,
0x37, 0xe3, 0x87, 0x9f, 0xb0, 0x5e, 0x0e, 0xf3, 0x26,
0x85, 0xd5, 0xae, 0xc5, 0x06, 0x7c, 0xd7, 0xcc, 0x96,
0xfe, 0x4b, 0x26, 0x70, 0xb6, 0xea, 0xc3, 0x06, 0x6b,
0x1f, 0xcf, 0x56, 0x86, 0xb6, 0x85, 0x89, 0xaa, 0xfb,
0x7d, 0x62, 0x9b, 0x02, 0xd8, 0xf8, 0x62, 0x5c, 0xa3,
0x83, 0x36, 0x24, 0xd4, 0x80, 0x0f, 0xb0, 0x81, 0xb1,
0xcf, 0x94, 0xeb,
},
},
},
},
// Key 10
{"ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb",
65537,
"056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e79",
[]testEncryptOAEPMessage{
// Example 10.1
{
[]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,
0x95, 0xee, 0x5e, 0xaa, 0xd8, 0x6f, 0x40, 0xd0, 0xaa,
0x63, 0xbd, 0x33,
},
[]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,
0xe5, 0x74, 0x52, 0x3d, 0xfb, 0x42, 0x13, 0x9d, 0x68,
0xc3, 0xc5, 0xaf, 0xee, 0xe0, 0xbf, 0xe4, 0xcb, 0x79,
0x69, 0xcb, 0xf3, 0x82, 0xb8, 0x04, 0xd6, 0xe6, 0x13,
0x96, 0x14, 0x4e, 0x2d, 0x0e, 0x60, 0x74, 0x1f, 0x89,
0x93, 0xc3, 0x01, 0x4b, 0x58, 0xb9, 0xb1, 0x95, 0x7a,
0x8b, 0xab, 0xcd, 0x23, 0xaf, 0x85, 0x4f, 0x4c, 0x35,
0x6f, 0xb1, 0x66, 0x2a, 0xa7, 0x2b, 0xfc, 0xc7, 0xe5,
0x86, 0x55, 0x9d, 0xc4, 0x28, 0x0d, 0x16, 0x0c, 0x12,
0x67, 0x85, 0xa7, 0x23, 0xeb, 0xee, 0xbe, 0xff, 0x71,
0xf1, 0x15, 0x94, 0x44, 0x0a, 0xae, 0xf8, 0x7d, 0x10,
0x79, 0x3a, 0x87, 0x74, 0xa2, 0x39, 0xd4, 0xa0, 0x4c,
0x87, 0xfe, 0x14, 0x67, 0xb9, 0xda, 0xf8, 0x52, 0x08,
0xec, 0x6c, 0x72, 0x55, 0x79, 0x4a, 0x96, 0xcc, 0x29,
0x14, 0x2f, 0x9a, 0x8b, 0xd4, 0x18, 0xe3, 0xc1, 0xfd,
0x67, 0x34, 0x4b, 0x0c, 0xd0, 0x82, 0x9d, 0xf3, 0xb2,
0xbe, 0xc6, 0x02, 0x53, 0x19, 0x62, 0x93, 0xc6, 0xb3,
0x4d, 0x3f, 0x75, 0xd3, 0x2f, 0x21, 0x3d, 0xd4, 0x5c,
0x62, 0x73, 0xd5, 0x05, 0xad, 0xf4, 0xcc, 0xed, 0x10,
0x57, 0xcb, 0x75, 0x8f, 0xc2, 0x6a, 0xee, 0xfa, 0x44,
0x12, 0x55, 0xed, 0x4e, 0x64, 0xc1, 0x99, 0xee, 0x07,
0x5e, 0x7f, 0x16, 0x64, 0x61, 0x82, 0xfd, 0xb4, 0x64,
0x73, 0x9b, 0x68, 0xab, 0x5d, 0xaf, 0xf0, 0xe6, 0x3e,
0x95, 0x52, 0x01, 0x68, 0x24, 0xf0, 0x54, 0xbf, 0x4d,
0x3c, 0x8c, 0x90, 0xa9, 0x7b, 0xb6, 0xb6, 0x55, 0x32,
0x84, 0xeb, 0x42, 0x9f, 0xcc,
},
},
},
},
}
/rsa/rsa.go
0,0 → 1,494
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package rsa implements RSA encryption as specified in PKCS#1.
package rsa
 
// TODO(agl): Add support for PSS padding.
 
import (
"crypto/rand"
"crypto/subtle"
"errors"
"hash"
"io"
"math/big"
)
 
var bigZero = big.NewInt(0)
var bigOne = big.NewInt(1)
 
// A PublicKey represents the public part of an RSA key.
type PublicKey struct {
N *big.Int // modulus
E int // public exponent
}
 
// A PrivateKey represents an RSA key
type PrivateKey struct {
PublicKey // public part.
D *big.Int // private exponent
Primes []*big.Int // prime factors of N, has >= 2 elements.
 
// Precomputed contains precomputed values that speed up private
// operations, if available.
Precomputed PrecomputedValues
}
 
type PrecomputedValues struct {
Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
Qinv *big.Int // Q^-1 mod Q
 
// CRTValues is used for the 3rd and subsequent primes. Due to a
// historical accident, the CRT for the first two primes is handled
// differently in PKCS#1 and interoperability is sufficiently
// important that we mirror this.
CRTValues []CRTValue
}
 
// CRTValue contains the precomputed chinese remainder theorem values.
type CRTValue struct {
Exp *big.Int // D mod (prime-1).
Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
R *big.Int // product of primes prior to this (inc p and q).
}
 
// Validate performs basic sanity checks on the key.
// It returns nil if the key is valid, or else an error describing a problem.
func (priv *PrivateKey) Validate() error {
// Check that the prime factors are actually prime. Note that this is
// just a sanity check. Since the random witnesses chosen by
// ProbablyPrime are deterministic, given the candidate number, it's
// easy for an attack to generate composites that pass this test.
for _, prime := range priv.Primes {
if !prime.ProbablyPrime(20) {
return errors.New("prime factor is composite")
}
}
 
// Check that Πprimes == n.
modulus := new(big.Int).Set(bigOne)
for _, prime := range priv.Primes {
modulus.Mul(modulus, prime)
}
if modulus.Cmp(priv.N) != 0 {
return errors.New("invalid modulus")
}
// Check that e and totient(Πprimes) are coprime.
totient := new(big.Int).Set(bigOne)
for _, prime := range priv.Primes {
pminus1 := new(big.Int).Sub(prime, bigOne)
totient.Mul(totient, pminus1)
}
e := big.NewInt(int64(priv.E))
gcd := new(big.Int)
x := new(big.Int)
y := new(big.Int)
gcd.GCD(x, y, totient, e)
if gcd.Cmp(bigOne) != 0 {
return errors.New("invalid public exponent E")
}
// Check that de ≡ 1 (mod totient(Πprimes))
de := new(big.Int).Mul(priv.D, e)
de.Mod(de, totient)
if de.Cmp(bigOne) != 0 {
return errors.New("invalid private exponent D")
}
return nil
}
 
// GenerateKey generates an RSA keypair of the given bit size.
func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
return GenerateMultiPrimeKey(random, 2, bits)
}
 
// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
// size, as suggested in [1]. Although the public keys are compatible
// (actually, indistinguishable) from the 2-prime case, the private keys are
// not. Thus it may not be possible to export multi-prime private keys in
// certain formats or to subsequently import them into other code.
//
// Table 1 in [2] suggests maximum numbers of primes for a given size.
//
// [1] US patent 4405829 (1972, expired)
// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (priv *PrivateKey, err error) {
priv = new(PrivateKey)
priv.E = 65537
 
if nprimes < 2 {
return nil, errors.New("rsa.GenerateMultiPrimeKey: nprimes must be >= 2")
}
 
primes := make([]*big.Int, nprimes)
 
NextSetOfPrimes:
for {
todo := bits
for i := 0; i < nprimes; i++ {
primes[i], err = rand.Prime(random, todo/(nprimes-i))
if err != nil {
return nil, err
}
todo -= primes[i].BitLen()
}
 
// Make sure that primes is pairwise unequal.
for i, prime := range primes {
for j := 0; j < i; j++ {
if prime.Cmp(primes[j]) == 0 {
continue NextSetOfPrimes
}
}
}
 
n := new(big.Int).Set(bigOne)
totient := new(big.Int).Set(bigOne)
pminus1 := new(big.Int)
for _, prime := range primes {
n.Mul(n, prime)
pminus1.Sub(prime, bigOne)
totient.Mul(totient, pminus1)
}
 
g := new(big.Int)
priv.D = new(big.Int)
y := new(big.Int)
e := big.NewInt(int64(priv.E))
g.GCD(priv.D, y, e, totient)
 
if g.Cmp(bigOne) == 0 {
priv.D.Add(priv.D, totient)
priv.Primes = primes
priv.N = n
 
break
}
}
 
priv.Precompute()
return
}
 
// incCounter increments a four byte, big-endian counter.
func incCounter(c *[4]byte) {
if c[3]++; c[3] != 0 {
return
}
if c[2]++; c[2] != 0 {
return
}
if c[1]++; c[1] != 0 {
return
}
c[0]++
}
 
// mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function
// specified in PKCS#1 v2.1.
func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
var counter [4]byte
var digest []byte
 
done := 0
for done < len(out) {
hash.Write(seed)
hash.Write(counter[0:4])
digest = hash.Sum(digest[:0])
hash.Reset()
 
for i := 0; i < len(digest) && done < len(out); i++ {
out[done] ^= digest[i]
done++
}
incCounter(&counter)
}
}
 
// MessageTooLongError is returned when attempting to encrypt a message which
// is too large for the size of the public key.
type MessageTooLongError struct{}
 
func (MessageTooLongError) Error() string {
return "message too long for RSA public key size"
}
 
func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
 
// EncryptOAEP encrypts the given message with RSA-OAEP.
// The message must be no longer than the length of the public modulus less
// twice the hash length plus 2.
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
hash.Reset()
k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-2*hash.Size()-2 {
err = MessageTooLongError{}
return
}
 
hash.Write(label)
lHash := hash.Sum(nil)
hash.Reset()
 
em := make([]byte, k)
seed := em[1 : 1+hash.Size()]
db := em[1+hash.Size():]
 
copy(db[0:hash.Size()], lHash)
db[len(db)-len(msg)-1] = 1
copy(db[len(db)-len(msg):], msg)
 
_, err = io.ReadFull(random, seed)
if err != nil {
return
}
 
mgf1XOR(db, hash, seed)
mgf1XOR(seed, hash, db)
 
m := new(big.Int)
m.SetBytes(em)
c := encrypt(new(big.Int), pub, m)
out = c.Bytes()
 
if len(out) < k {
// If the output is too small, we need to left-pad with zeros.
t := make([]byte, k)
copy(t[k-len(out):], out)
out = t
}
 
return
}
 
// A DecryptionError represents a failure to decrypt a message.
// It is deliberately vague to avoid adaptive attacks.
type DecryptionError struct{}
 
func (DecryptionError) Error() string { return "RSA decryption error" }
 
// A VerificationError represents a failure to verify a signature.
// It is deliberately vague to avoid adaptive attacks.
type VerificationError struct{}
 
func (VerificationError) Error() string { return "RSA verification error" }
 
// modInverse returns ia, the inverse of a in the multiplicative group of prime
// order n. It requires that a be a member of the group (i.e. less than n).
func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
g := new(big.Int)
x := new(big.Int)
y := new(big.Int)
g.GCD(x, y, a, n)
if g.Cmp(bigOne) != 0 {
// In this case, a and n aren't coprime and we cannot calculate
// the inverse. This happens because the values of n are nearly
// prime (being the product of two primes) rather than truly
// prime.
return
}
 
if x.Cmp(bigOne) < 0 {
// 0 is not the multiplicative inverse of any element so, if x
// < 1, then x is negative.
x.Add(x, n)
}
 
return x, true
}
 
// Precompute performs some calculations that speed up private key operations
// in the future.
func (priv *PrivateKey) Precompute() {
if priv.Precomputed.Dp != nil {
return
}
 
priv.Precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
priv.Precomputed.Dp.Mod(priv.D, priv.Precomputed.Dp)
 
priv.Precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
priv.Precomputed.Dq.Mod(priv.D, priv.Precomputed.Dq)
 
priv.Precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
 
r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
priv.Precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
for i := 2; i < len(priv.Primes); i++ {
prime := priv.Primes[i]
values := &priv.Precomputed.CRTValues[i-2]
 
values.Exp = new(big.Int).Sub(prime, bigOne)
values.Exp.Mod(priv.D, values.Exp)
 
values.R = new(big.Int).Set(r)
values.Coeff = new(big.Int).ModInverse(r, prime)
 
r.Mul(r, prime)
}
}
 
// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
// random source is given, RSA blinding is used.
func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
// TODO(agl): can we get away with reusing blinds?
if c.Cmp(priv.N) > 0 {
err = DecryptionError{}
return
}
 
var ir *big.Int
if random != nil {
// Blinding enabled. Blinding involves multiplying c by r^e.
// Then the decryption operation performs (m^e * r^e)^d mod n
// which equals mr mod n. The factor of r can then be removed
// by multiplying by the multiplicative inverse of r.
 
var r *big.Int
 
for {
r, err = rand.Int(random, priv.N)
if err != nil {
return
}
if r.Cmp(bigZero) == 0 {
r = bigOne
}
var ok bool
ir, ok = modInverse(r, priv.N)
if ok {
break
}
}
bigE := big.NewInt(int64(priv.E))
rpowe := new(big.Int).Exp(r, bigE, priv.N)
cCopy := new(big.Int).Set(c)
cCopy.Mul(cCopy, rpowe)
cCopy.Mod(cCopy, priv.N)
c = cCopy
}
 
if priv.Precomputed.Dp == nil {
m = new(big.Int).Exp(c, priv.D, priv.N)
} else {
// We have the precalculated values needed for the CRT.
m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
m.Sub(m, m2)
if m.Sign() < 0 {
m.Add(m, priv.Primes[0])
}
m.Mul(m, priv.Precomputed.Qinv)
m.Mod(m, priv.Primes[0])
m.Mul(m, priv.Primes[1])
m.Add(m, m2)
 
for i, values := range priv.Precomputed.CRTValues {
prime := priv.Primes[2+i]
m2.Exp(c, values.Exp, prime)
m2.Sub(m2, m)
m2.Mul(m2, values.Coeff)
m2.Mod(m2, prime)
if m2.Sign() < 0 {
m2.Add(m2, prime)
}
m2.Mul(m2, values.R)
m.Add(m, m2)
}
}
 
if ir != nil {
// Unblind.
m.Mul(m, ir)
m.Mod(m, priv.N)
}
 
return
}
 
// DecryptOAEP decrypts ciphertext using RSA-OAEP.
// If random != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks.
func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err error) {
k := (priv.N.BitLen() + 7) / 8
if len(ciphertext) > k ||
k < hash.Size()*2+2 {
err = DecryptionError{}
return
}
 
c := new(big.Int).SetBytes(ciphertext)
 
m, err := decrypt(random, priv, c)
if err != nil {
return
}
 
hash.Write(label)
lHash := hash.Sum(nil)
hash.Reset()
 
// Converting the plaintext number to bytes will strip any
// leading zeros so we may have to left pad. We do this unconditionally
// to avoid leaking timing information. (Although we still probably
// leak the number of leading zeros. It's not clear that we can do
// anything about this.)
em := leftPad(m.Bytes(), k)
 
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
 
seed := em[1 : hash.Size()+1]
db := em[hash.Size()+1:]
 
mgf1XOR(seed, hash, db)
mgf1XOR(db, hash, seed)
 
lHash2 := db[0:hash.Size()]
 
// We have to validate the plaintext in constant time in order to avoid
// attacks like: J. Manger. A Chosen Ciphertext Attack on RSA Optimal
// Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1
// v2.0. In J. Kilian, editor, Advances in Cryptology.
lHash2Good := subtle.ConstantTimeCompare(lHash, lHash2)
 
// The remainder of the plaintext must be zero or more 0x00, followed
// by 0x01, followed by the message.
// lookingForIndex: 1 iff we are still looking for the 0x01
// index: the offset of the first 0x01 byte
// invalid: 1 iff we saw a non-zero byte before the 0x01.
var lookingForIndex, index, invalid int
lookingForIndex = 1
rest := db[hash.Size():]
 
for i := 0; i < len(rest); i++ {
equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
}
 
if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
err = DecryptionError{}
return
}
 
msg = rest[index+1:]
return
}
 
// leftPad returns a new slice of length size. The contents of input are right
// aligned in the new slice.
func leftPad(input []byte, size int) (out []byte) {
n := len(input)
if n > size {
n = size
}
out = make([]byte, size)
copy(out[len(out)-n:], input)
return
}
/rc4/rc4_test.go
0,0 → 1,59
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package rc4
 
import (
"testing"
)
 
type rc4Test struct {
key, keystream []byte
}
 
var golden = []rc4Test{
// Test vectors from the original cypherpunk posting of ARC4:
// http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0?pli=1
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79},
},
{
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a},
},
{
[]byte{0xef, 0x01, 0x23, 0x45},
[]byte{0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, 0xbd, 0x61},
},
 
// Test vectors from the Wikipedia page: http://en.wikipedia.org/wiki/RC4
{
[]byte{0x4b, 0x65, 0x79},
[]byte{0xeb, 0x9f, 0x77, 0x81, 0xb7, 0x34, 0xca, 0x72, 0xa7, 0x19},
},
{
[]byte{0x57, 0x69, 0x6b, 0x69},
[]byte{0x60, 0x44, 0xdb, 0x6d, 0x41, 0xb7},
},
}
 
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c, err := NewCipher(g.key)
if err != nil {
t.Errorf("Failed to create cipher at golden index %d", i)
return
}
keystream := make([]byte, len(g.keystream))
c.XORKeyStream(keystream, keystream)
for j, v := range keystream {
if g.keystream[j] != v {
t.Errorf("Failed at golden index %d", i)
break
}
}
}
}
/rc4/rc4.go
0,0 → 1,63
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package rc4 implements RC4 encryption, as defined in Bruce Schneier's
// Applied Cryptography.
package rc4
 
// BUG(agl): RC4 is in common use but has design weaknesses that make
// it a poor choice for new protocols.
 
import "strconv"
 
// A Cipher is an instance of RC4 using a particular key.
type Cipher struct {
s [256]byte
i, j uint8
}
 
type KeySizeError int
 
func (k KeySizeError) Error() string {
return "crypto/rc4: invalid key size " + strconv.Itoa(int(k))
}
 
// NewCipher creates and returns a new Cipher. The key argument should be the
// RC4 key, at least 1 byte and at most 256 bytes.
func NewCipher(key []byte) (*Cipher, error) {
k := len(key)
if k < 1 || k > 256 {
return nil, KeySizeError(k)
}
var c Cipher
for i := 0; i < 256; i++ {
c.s[i] = uint8(i)
}
var j uint8 = 0
for i := 0; i < 256; i++ {
j += c.s[i] + key[i%k]
c.s[i], c.s[j] = c.s[j], c.s[i]
}
return &c, nil
}
 
// XORKeyStream sets dst to the result of XORing src with the key stream.
// Dst and src may be the same slice but otherwise should not overlap.
func (c *Cipher) XORKeyStream(dst, src []byte) {
for i := range src {
c.i += 1
c.j += c.s[c.i]
c.s[c.i], c.s[c.j] = c.s[c.j], c.s[c.i]
dst[i] = src[i] ^ c.s[c.s[c.i]+c.s[c.j]]
}
}
 
// Reset zeros the key data so that it will no longer appear in the
// process's memory.
func (c *Cipher) Reset() {
for i := range c.s {
c.s[i] = 0
}
c.i, c.j = 0, 0
}
/sha1/sha1_test.go
0,0 → 1,73
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// SHA1 hash algorithm. See RFC 3174.
 
package sha1
 
import (
"fmt"
"io"
"testing"
)
 
type sha1Test struct {
out string
in string
}
 
var golden = []sha1Test{
{"da39a3ee5e6b4b0d3255bfef95601890afd80709", ""},
{"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a"},
{"da23614e02469a0d7c7bd1bdab5c9c474b1904dc", "ab"},
{"a9993e364706816aba3e25717850c26c9cd0d89d", "abc"},
{"81fe8bfe87576c3ecb22426f8e57847382917acf", "abcd"},
{"03de6c570bfe24bfc328ccd7ca46b76eadaf4334", "abcde"},
{"1f8ac10f23c5b5bc1167bda84b833e5c057a77d2", "abcdef"},
{"2fb5e13419fc89246865e7a324f476ec624e8740", "abcdefg"},
{"425af12a0743502b322e93a015bcf868e324d56a", "abcdefgh"},
{"c63b19f1e4c8b5f76b25c49b8b87f57d8e4872a1", "abcdefghi"},
{"d68c19a0a345b7eab78d5e11e991c026ec60db63", "abcdefghij"},
{"ebf81ddcbe5bf13aaabdc4d65354fdf2044f38a7", "Discard medicine more than two years old."},
{"e5dea09392dd886ca63531aaa00571dc07554bb6", "He who has a shady past knows that nice guys finish last."},
{"45988f7234467b94e3e9494434c96ee3609d8f8f", "I wouldn't marry him with a ten foot pole."},
{"55dee037eb7460d5a692d1ce11330b260e40c988", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
{"b7bc5fb91080c7de6b582ea281f8a396d7c0aee8", "The days of the digital watch are numbered. -Tom Stoppard"},
{"c3aed9358f7c77f523afe86135f06b95b3999797", "Nepal premier won't resign."},
{"6e29d302bf6e3a5e4305ff318d983197d6906bb9", "For every action there is an equal and opposite government program."},
{"597f6a540010f94c15d71806a99a2c8710e747bd", "His money is twice tainted: 'taint yours and 'taint mine."},
{"6859733b2590a8a091cecf50086febc5ceef1e80", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
{"514b2630ec089b8aee18795fc0cf1f4860cdacad", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
{"c5ca0d4a7b6676fc7aa72caa41cc3d5df567ed69", "size: a.out: bad magic"},
{"74c51fa9a04eadc8c1bbeaa7fc442f834b90a00a", "The major problem is with sendmail. -Mark Horton"},
{"0b4c4ce5f52c3ad2821852a8dc00217fa18b8b66", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
{"3ae7937dd790315beb0f48330e8642237c61550a", "If the enemy is within range, then so are you."},
{"410a2b296df92b9a47412b13281df8f830a9f44b", "It's well we cannot hear the screams/That we create in others' dreams."},
{"841e7c85ca1adcddbdd0187f1289acb5c642f7f5", "You remind me of a TV show, but that's all right: I watch it anyway."},
{"163173b825d03b952601376b25212df66763e1db", "C is as portable as Stonehedge!!"},
{"32b0377f2687eb88e22106f133c586ab314d5279", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
{"0885aaf99b569542fd165fa44e322718f4a984e0", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
{"6627d6904d71420b0bf3886ab629623538689f45", "How can you write a big system without C++? -Paul Glick"},
}
 
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("sha1[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
}
/sha1/sha1.go
0,0 → 1,121
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package sha1 implements the SHA1 hash algorithm as defined in RFC 3174.
package sha1
 
import (
"crypto"
"hash"
)
 
func init() {
crypto.RegisterHash(crypto.SHA1, New)
}
 
// The size of a SHA1 checksum in bytes.
const Size = 20
 
// The blocksize of SHA1 in bytes.
const BlockSize = 64
 
const (
_Chunk = 64
_Init0 = 0x67452301
_Init1 = 0xEFCDAB89
_Init2 = 0x98BADCFE
_Init3 = 0x10325476
_Init4 = 0xC3D2E1F0
)
 
// digest represents the partial evaluation of a checksum.
type digest struct {
h [5]uint32
x [_Chunk]byte
nx int
len uint64
}
 
func (d *digest) Reset() {
d.h[0] = _Init0
d.h[1] = _Init1
d.h[2] = _Init2
d.h[3] = _Init3
d.h[4] = _Init4
d.nx = 0
d.len = 0
}
 
// New returns a new hash.Hash computing the SHA1 checksum.
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
 
func (d *digest) Size() int { return Size }
 
func (d *digest) BlockSize() int { return BlockSize }
 
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.len += uint64(nn)
if d.nx > 0 {
n := len(p)
if n > _Chunk-d.nx {
n = _Chunk - d.nx
}
for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i]
}
d.nx += n
if d.nx == _Chunk {
_Block(d, d.x[0:])
d.nx = 0
}
p = p[n:]
}
n := _Block(d, p)
p = p[n:]
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
 
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := *d0
 
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
tmp[0] = 0x80
if len%64 < 56 {
d.Write(tmp[0 : 56-len%64])
} else {
d.Write(tmp[0 : 64+56-len%64])
}
 
// Length in bits.
len <<= 3
for i := uint(0); i < 8; i++ {
tmp[i] = byte(len >> (56 - 8*i))
}
d.Write(tmp[0:8])
 
if d.nx != 0 {
panic("d.nx != 0")
}
 
var digest [Size]byte
for i, s := range d.h {
digest[i*4] = byte(s >> 24)
digest[i*4+1] = byte(s >> 16)
digest[i*4+2] = byte(s >> 8)
digest[i*4+3] = byte(s)
}
 
return append(in, digest[:]...)
}
/sha1/sha1block.go
0,0 → 1,81
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// SHA1 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
 
package sha1
 
const (
_K0 = 0x5A827999
_K1 = 0x6ED9EBA1
_K2 = 0x8F1BBCDC
_K3 = 0xCA62C1D6
)
 
func _Block(dig *digest, p []byte) int {
var w [80]uint32
 
n := 0
h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4]
for len(p) >= _Chunk {
// Can interlace the computation of w with the
// rounds below if needed for speed.
for i := 0; i < 16; i++ {
j := i * 4
w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
}
for i := 16; i < 80; i++ {
tmp := w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]
w[i] = tmp<<1 | tmp>>(32-1)
}
 
a, b, c, d, e := h0, h1, h2, h3, h4
 
// Each of the four 20-iteration rounds
// differs only in the computation of f and
// the choice of K (_K0, _K1, etc).
for i := 0; i < 20; i++ {
f := b&c | (^b)&d
a5 := a<<5 | a>>(32-5)
b30 := b<<30 | b>>(32-30)
t := a5 + f + e + w[i] + _K0
a, b, c, d, e = t, a, b30, c, d
}
for i := 20; i < 40; i++ {
f := b ^ c ^ d
a5 := a<<5 | a>>(32-5)
b30 := b<<30 | b>>(32-30)
t := a5 + f + e + w[i] + _K1
a, b, c, d, e = t, a, b30, c, d
}
for i := 40; i < 60; i++ {
f := b&c | b&d | c&d
a5 := a<<5 | a>>(32-5)
b30 := b<<30 | b>>(32-30)
t := a5 + f + e + w[i] + _K2
a, b, c, d, e = t, a, b30, c, d
}
for i := 60; i < 80; i++ {
f := b ^ c ^ d
a5 := a<<5 | a>>(32-5)
b30 := b<<30 | b>>(32-30)
t := a5 + f + e + w[i] + _K3
a, b, c, d, e = t, a, b30, c, d
}
 
h0 += a
h1 += b
h2 += c
h3 += d
h4 += e
 
p = p[_Chunk:]
n += _Chunk
}
 
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4
return n
}
/subtle/constant_time_test.go
0,0 → 1,105
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package subtle
 
import (
"testing"
"testing/quick"
)
 
type TestConstantTimeCompareStruct struct {
a, b []byte
out int
}
 
var testConstantTimeCompareData = []TestConstantTimeCompareStruct{
{[]byte{}, []byte{}, 1},
{[]byte{0x11}, []byte{0x11}, 1},
{[]byte{0x12}, []byte{0x11}, 0},
}
 
func TestConstantTimeCompare(t *testing.T) {
for i, test := range testConstantTimeCompareData {
if r := ConstantTimeCompare(test.a, test.b); r != test.out {
t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out)
}
}
}
 
type TestConstantTimeByteEqStruct struct {
a, b uint8
out int
}
 
var testConstandTimeByteEqData = []TestConstantTimeByteEqStruct{
{0, 0, 1},
{0, 1, 0},
{1, 0, 0},
{0xff, 0xff, 1},
{0xff, 0xfe, 0},
}
 
func byteEq(a, b uint8) int {
if a == b {
return 1
}
return 0
}
 
func TestConstantTimeByteEq(t *testing.T) {
for i, test := range testConstandTimeByteEqData {
if r := ConstantTimeByteEq(test.a, test.b); r != test.out {
t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out)
}
}
err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil)
if err != nil {
t.Error(err)
}
}
 
func eq(a, b int32) int {
if a == b {
return 1
}
return 0
}
 
func TestConstantTimeEq(t *testing.T) {
err := quick.CheckEqual(ConstantTimeEq, eq, nil)
if err != nil {
t.Error(err)
}
}
 
func makeCopy(v int, x, y []byte) []byte {
if len(x) > len(y) {
x = x[0:len(y)]
} else {
y = y[0:len(x)]
}
if v == 1 {
copy(x, y)
}
return x
}
 
func constantTimeCopyWrapper(v int, x, y []byte) []byte {
if len(x) > len(y) {
x = x[0:len(y)]
} else {
y = y[0:len(x)]
}
v &= 1
ConstantTimeCopy(v, x, y)
return x
}
 
func TestConstantTimeCopy(t *testing.T) {
err := quick.CheckEqual(constantTimeCopyWrapper, makeCopy, nil)
if err != nil {
t.Error(err)
}
}
/subtle/constant_time.go
0,0 → 1,57
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle
 
// ConstantTimeCompare returns 1 iff the two equal length slices, x
// and y, have equal contents. The time taken is a function of the length of
// the slices and is independent of the contents.
func ConstantTimeCompare(x, y []byte) int {
var v byte
 
for i := 0; i < len(x); i++ {
v |= x[i] ^ y[i]
}
 
return ConstantTimeByteEq(v, 0)
}
 
// ConstantTimeSelect returns x if v is 1 and y if v is 0.
// Its behavior is undefined if v takes any other value.
func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y }
 
// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
func ConstantTimeByteEq(x, y uint8) int {
z := ^(x ^ y)
z &= z >> 4
z &= z >> 2
z &= z >> 1
 
return int(z)
}
 
// ConstantTimeEq returns 1 if x == y and 0 otherwise.
func ConstantTimeEq(x, y int32) int {
z := ^(x ^ y)
z &= z >> 16
z &= z >> 8
z &= z >> 4
z &= z >> 2
z &= z >> 1
 
return int(z & 1)
}
 
// ConstantTimeCopy copies the contents of y into x iff v == 1. If v == 0, x is left unchanged.
// Its behavior is undefined if v takes any other value.
func ConstantTimeCopy(v int, x, y []byte) {
xmask := byte(v - 1)
ymask := byte(^(v - 1))
for i := 0; i < len(x); i++ {
x[i] = x[i]&xmask | y[i]&ymask
}
return
}
/tls/handshake_server_test.go
0,0 → 1,1570
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"bytes"
"crypto/rsa"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"flag"
"io"
"log"
"math/big"
"net"
"strconv"
"strings"
"testing"
"time"
)
 
type zeroSource struct{}
 
func (zeroSource) Read(b []byte) (n int, err error) {
for i := range b {
b[i] = 0
}
 
return len(b), nil
}
 
var testConfig *Config
 
func init() {
testConfig = new(Config)
testConfig.Time = func() time.Time { return time.Unix(0, 0) }
testConfig.Rand = zeroSource{}
testConfig.Certificates = make([]Certificate, 1)
testConfig.Certificates[0].Certificate = [][]byte{testCertificate}
testConfig.Certificates[0].PrivateKey = testPrivateKey
testConfig.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
testConfig.InsecureSkipVerify = true
}
 
func testClientHelloFailure(t *testing.T, m handshakeMessage, expected error) {
// Create in-memory network connection,
// send message to server. Should return
// expected error.
c, s := net.Pipe()
go func() {
cli := Client(c, testConfig)
if ch, ok := m.(*clientHelloMsg); ok {
cli.vers = ch.vers
}
cli.writeRecord(recordTypeHandshake, m.marshal())
c.Close()
}()
err := Server(s, testConfig).Handshake()
s.Close()
if e, ok := err.(*net.OpError); !ok || e.Err != expected {
t.Errorf("Got error: %s; expected: %s", err, expected)
}
}
 
func TestSimpleError(t *testing.T) {
testClientHelloFailure(t, &serverHelloDoneMsg{}, alertUnexpectedMessage)
}
 
var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
 
func TestRejectBadProtocolVersion(t *testing.T) {
for _, v := range badProtocolVersions {
testClientHelloFailure(t, &clientHelloMsg{vers: v}, alertProtocolVersion)
}
}
 
func TestNoSuiteOverlap(t *testing.T) {
clientHello := &clientHelloMsg{nil, 0x0301, nil, nil, []uint16{0xff00}, []uint8{0}, false, "", false, nil, nil}
testClientHelloFailure(t, clientHello, alertHandshakeFailure)
 
}
 
func TestNoCompressionOverlap(t *testing.T) {
clientHello := &clientHelloMsg{nil, 0x0301, nil, nil, []uint16{TLS_RSA_WITH_RC4_128_SHA}, []uint8{0xff}, false, "", false, nil, nil}
testClientHelloFailure(t, clientHello, alertHandshakeFailure)
}
 
func TestAlertForwarding(t *testing.T) {
c, s := net.Pipe()
go func() {
Client(c, testConfig).sendAlert(alertUnknownCA)
c.Close()
}()
 
err := Server(s, testConfig).Handshake()
s.Close()
if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) {
t.Errorf("Got error: %s; expected: %s", err, alertUnknownCA)
}
}
 
func TestClose(t *testing.T) {
c, s := net.Pipe()
go c.Close()
 
err := Server(s, testConfig).Handshake()
s.Close()
if err != io.EOF {
t.Errorf("Got error: %s; expected: %s", err, io.EOF)
}
}
 
func testServerScript(t *testing.T, name string, serverScript [][]byte, config *Config, peers []*x509.Certificate) {
c, s := net.Pipe()
srv := Server(s, config)
pchan := make(chan []*x509.Certificate, 1)
go func() {
srv.Write([]byte("hello, world\n"))
srv.Close()
s.Close()
st := srv.ConnectionState()
pchan <- st.PeerCertificates
}()
 
for i, b := range serverScript {
if i%2 == 0 {
c.Write(b)
continue
}
bb := make([]byte, len(b))
n, err := io.ReadFull(c, bb)
if err != nil {
t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", name, i, err, n, len(bb), bb[:n], b)
}
if !bytes.Equal(b, bb) {
t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b)
}
}
c.Close()
 
if peers != nil {
gotpeers := <-pchan
if len(peers) == len(gotpeers) {
for i, _ := range peers {
if !peers[i].Equal(gotpeers[i]) {
t.Fatalf("%s: mismatch on peer cert %d", name, i)
}
}
} else {
t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", name, len(peers), len(gotpeers))
}
}
}
 
func TestHandshakeServerRC4(t *testing.T) {
testServerScript(t, "RC4", rc4ServerScript, testConfig, nil)
}
 
func TestHandshakeServer3DES(t *testing.T) {
des3Config := new(Config)
*des3Config = *testConfig
des3Config.CipherSuites = []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}
testServerScript(t, "3DES", des3ServerScript, des3Config, nil)
}
 
func TestHandshakeServerAES(t *testing.T) {
aesConfig := new(Config)
*aesConfig = *testConfig
aesConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}
testServerScript(t, "AES", aesServerScript, aesConfig, nil)
}
 
func TestHandshakeServerSSLv3(t *testing.T) {
testServerScript(t, "SSLv3", sslv3ServerScript, testConfig, nil)
}
 
type clientauthTest struct {
name string
clientauth ClientAuthType
peers []*x509.Certificate
script [][]byte
}
 
func TestClientAuth(t *testing.T) {
for _, cat := range clientauthTests {
t.Log("running", cat.name)
cfg := new(Config)
*cfg = *testConfig
cfg.ClientAuth = cat.clientauth
testServerScript(t, cat.name, cat.script, cfg, cat.peers)
}
}
 
var serve = flag.Bool("serve", false, "run a TLS server on :10443")
var testCipherSuites = flag.String("ciphersuites",
"0x"+strconv.FormatInt(int64(TLS_RSA_WITH_RC4_128_SHA), 16),
"cipher suites to accept in serving mode")
var testClientAuth = flag.Int("clientauth", 0, "value for tls.Config.ClientAuth")
 
func TestRunServer(t *testing.T) {
if !*serve {
return
}
 
suites := strings.Split(*testCipherSuites, ",")
testConfig.CipherSuites = make([]uint16, len(suites))
for i := range suites {
suite, err := strconv.ParseUint(suites[i], 0, 64)
if err != nil {
panic(err)
}
testConfig.CipherSuites[i] = uint16(suite)
}
 
testConfig.ClientAuth = ClientAuthType(*testClientAuth)
 
l, err := Listen("tcp", ":10443", testConfig)
if err != nil {
t.Fatal(err)
}
 
for {
c, err := l.Accept()
if err != nil {
log.Printf("error from TLS handshake: %s", err)
break
}
 
_, err = c.Write([]byte("hello, world\n"))
if err != nil {
log.Printf("error from TLS: %s", err)
continue
}
 
st := c.(*Conn).ConnectionState()
if len(st.PeerCertificates) > 0 {
log.Print("Handling request from client ", st.PeerCertificates[0].Subject.CommonName)
} else {
log.Print("Handling request from anon client")
}
 
c.Close()
}
}
 
func bigFromString(s string) *big.Int {
ret := new(big.Int)
ret.SetString(s, 10)
return ret
}
 
func fromHex(s string) []byte {
b, _ := hex.DecodeString(s)
return b
}
 
var testCertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9")
 
var testPrivateKey = &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"),
E: 65537,
},
D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"),
Primes: []*big.Int{
bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"),
bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"),
},
}
 
func loadPEMCert(in string) *x509.Certificate {
block, _ := pem.Decode([]byte(in))
if block.Type == "CERTIFICATE" && len(block.Headers) == 0 {
cert, err := x509.ParseCertificate(block.Bytes)
if err == nil {
return cert
}
panic("error parsing cert")
}
panic("error parsing PEM")
}
 
// Script of interaction with gnutls implementation.
// The values for this test are obtained by building and running in server mode:
// % gotest -test.run "TestRunServer" -serve
// and then:
// % gnutls-cli --insecure --debug 100 -p 10443 localhost > /tmp/log 2>&1
// % python parse-gnutls-cli-debug-log.py < /tmp/log
var rc4ServerScript = [][]byte{
{
0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
0x76, 0x03, 0x02, 0x4e, 0xdd, 0xe6, 0xa5, 0xf7,
0x00, 0x36, 0xf7, 0x83, 0xec, 0x93, 0x7c, 0xd2,
0x4d, 0xe7, 0x7b, 0xf5, 0x4c, 0xf7, 0xe3, 0x86,
0xe8, 0xec, 0x3b, 0xbd, 0x2c, 0x9a, 0x3f, 0x57,
0xf0, 0xa4, 0xd4, 0x00, 0x00, 0x34, 0x00, 0x33,
0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e,
0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0x39, 0xe2, 0x0f, 0x49, 0xa0,
0xe6, 0xe4, 0x3b, 0x0c, 0x5f, 0xce, 0x39, 0x97,
0x6c, 0xb6, 0x41, 0xd9, 0xe1, 0x52, 0x8f, 0x43,
0xb3, 0xc6, 0x4f, 0x9a, 0xe2, 0x1e, 0xb9, 0x3b,
0xe3, 0x72, 0x17, 0x68, 0xb2, 0x0d, 0x7b, 0x71,
0x33, 0x96, 0x5c, 0xf9, 0xfe, 0x18, 0x8f, 0x2f,
0x2b, 0x82, 0xec, 0x03, 0xf2, 0x16, 0xa8, 0xf8,
0x39, 0xf9, 0xbb, 0x5a, 0xd3, 0x0c, 0xc1, 0x2a,
0x52, 0xa1, 0x90, 0x20, 0x6b, 0x24, 0xc9, 0x55,
0xee, 0x05, 0xd8, 0xb3, 0x43, 0x58, 0xf6, 0x7f,
0x68, 0x2d, 0xb3, 0xd1, 0x1b, 0x30, 0xaa, 0xdf,
0xfc, 0x85, 0xf1, 0xab, 0x14, 0x51, 0x91, 0x78,
0x29, 0x35, 0x65, 0xe0, 0x9c, 0xf6, 0xb7, 0x35,
0x33, 0xdb, 0x28, 0x93, 0x4d, 0x86, 0xbc, 0xfe,
0xaa, 0xd1, 0xc0, 0x2e, 0x4d, 0xec, 0xa2, 0x98,
0xca, 0x08, 0xb2, 0x91, 0x14, 0xde, 0x97, 0x3a,
0xc4, 0x6b, 0x49, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0x7a, 0xcb,
0x3b, 0x0e, 0xbb, 0x7a, 0x56, 0x39, 0xaf, 0x83,
0xae, 0xfd, 0x25, 0xfd, 0x64, 0xb4, 0x0c, 0x0c,
0x17, 0x46, 0x54, 0x2c, 0x6a, 0x07, 0x83, 0xc6,
0x46, 0x08, 0x0b, 0xcd, 0x15, 0x53, 0xef, 0x40,
0x4e, 0x56,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x24, 0xd3, 0x72, 0xeb, 0x29, 0xb9,
0x15, 0x29, 0xb5, 0xe5, 0xb7, 0xef, 0x5c, 0xb2,
0x9d, 0xf6, 0xc8, 0x47, 0xd6, 0xa0, 0x84, 0xf0,
0x8c, 0xcb, 0xe6, 0xbe, 0xbc, 0xfb, 0x38, 0x90,
0x89, 0x60, 0xa2, 0xe8, 0xaa, 0xb3, 0x12, 0x17,
0x03, 0x01, 0x00, 0x21, 0x67, 0x4a, 0x3d, 0x31,
0x6c, 0x5a, 0x1c, 0xf9, 0x6e, 0xf1, 0xd8, 0x12,
0x0e, 0xb9, 0xfd, 0xfc, 0x66, 0x91, 0xd1, 0x1d,
0x6e, 0xe4, 0x55, 0xdd, 0x11, 0xb9, 0xb8, 0xa2,
0x65, 0xa1, 0x95, 0x64, 0x1c, 0x15, 0x03, 0x01,
0x00, 0x16, 0x9b, 0xa0, 0x24, 0xe3, 0xcb, 0xae,
0xad, 0x51, 0xb3, 0x63, 0x59, 0x78, 0x49, 0x24,
0x06, 0x6e, 0xee, 0x7a, 0xd7, 0x74, 0x53, 0x04,
},
}
 
var des3ServerScript = [][]byte{
{
0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
0x76, 0x03, 0x02, 0x4e, 0x84, 0xf4, 0x3c, 0xe4,
0xb8, 0xc7, 0xa0, 0x30, 0x55, 0x2a, 0xbc, 0xb7,
0x04, 0x6b, 0x6f, 0x87, 0x93, 0x96, 0xbd, 0x1a,
0x7a, 0x1e, 0xce, 0xd2, 0x0d, 0xf3, 0x01, 0x03,
0xbe, 0x7b, 0x17, 0x00, 0x00, 0x34, 0x00, 0x33,
0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x16,
0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e,
0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0xae, 0xcf, 0x4f, 0x70, 0x0e,
0xe5, 0xe7, 0xba, 0xef, 0x0c, 0x66, 0xe9, 0xae,
0x76, 0xf4, 0xe0, 0xbc, 0x1c, 0x22, 0x5b, 0x72,
0xc9, 0x68, 0x63, 0x44, 0xec, 0x72, 0xc2, 0xca,
0xac, 0xc2, 0xf5, 0x5c, 0x28, 0xa1, 0xaf, 0xd0,
0xc2, 0xf7, 0x79, 0x71, 0x32, 0x73, 0x86, 0xea,
0x39, 0xf6, 0x04, 0x26, 0x19, 0x84, 0x1d, 0x7d,
0xa1, 0x21, 0xa6, 0x88, 0xbf, 0x33, 0x5a, 0x64,
0xb0, 0xc2, 0xcc, 0x19, 0x7a, 0x8b, 0x6e, 0x94,
0x9e, 0x2e, 0x20, 0xbe, 0xdc, 0xe9, 0x8e, 0xae,
0x5c, 0x39, 0xc8, 0xcd, 0x0e, 0x19, 0x9a, 0xa2,
0xfc, 0x3f, 0x61, 0x9a, 0xca, 0x58, 0x69, 0x0d,
0xa8, 0x7b, 0xbe, 0x98, 0x8f, 0xb9, 0x9d, 0x8b,
0x68, 0x65, 0xa9, 0x74, 0xcc, 0x8d, 0x0c, 0xb2,
0xc4, 0x0f, 0xdc, 0x56, 0x3e, 0x44, 0x61, 0x0a,
0x26, 0x93, 0x99, 0xef, 0x67, 0xff, 0x6e, 0x73,
0x01, 0xa1, 0x90, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x60, 0x49, 0x36,
0xc8, 0x38, 0x95, 0xe4, 0x5d, 0x8e, 0x80, 0x10,
0x26, 0x9f, 0x87, 0x7d, 0xcd, 0xb9, 0x32, 0x6c,
0xff, 0xaa, 0xe0, 0x07, 0xec, 0x33, 0xe2, 0x36,
0x9d, 0xd5, 0x83, 0x2c, 0xf0, 0x0a, 0xa0, 0xa8,
0x12, 0x9f, 0xca, 0x72, 0xda, 0x70, 0x7d, 0x76,
0x80, 0x12, 0x88, 0x07, 0xaa, 0x27, 0x62, 0x33,
0xab, 0x55, 0xad, 0x3c, 0x2b, 0x54, 0xc4, 0x1c,
0x91, 0xfd, 0x8f, 0x9c, 0xa7, 0x8b, 0x75, 0x10,
0xa8, 0x6e, 0xfc, 0x30, 0x52, 0x8a, 0x61, 0x02,
0xdb, 0x9c, 0x6f, 0xc8, 0x19, 0x93, 0x5d, 0x41,
0x1d, 0x36, 0x68, 0x0b, 0xec, 0x30, 0xae, 0xfb,
0x90, 0xdb, 0x6d, 0x83, 0xb0, 0xf2,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x28, 0x07, 0xf3, 0x33, 0x84, 0xb1,
0x5d, 0x2b, 0x52, 0xa4, 0x63, 0x3c, 0x32, 0xe0,
0x0d, 0x22, 0xf5, 0x23, 0xec, 0xf9, 0xa6, 0xec,
0xc0, 0x12, 0x69, 0x88, 0xf6, 0x7d, 0x37, 0xcd,
0xc2, 0x74, 0x2f, 0xef, 0xf6, 0x49, 0x15, 0xea,
0x88, 0x3f, 0x55, 0x17, 0x03, 0x01, 0x00, 0x28,
0xaf, 0x00, 0x84, 0xff, 0x11, 0x01, 0x6d, 0xba,
0x39, 0x5e, 0x45, 0xe1, 0x52, 0x5e, 0xc1, 0xab,
0xde, 0x5b, 0x16, 0xdd, 0xd6, 0x61, 0x57, 0xb8,
0x66, 0x8b, 0x2d, 0xde, 0x51, 0x41, 0xc5, 0x09,
0xb3, 0x6a, 0x06, 0x43, 0xb4, 0x73, 0x5c, 0xf1,
0x15, 0x03, 0x01, 0x00, 0x18, 0xbd, 0x65, 0xb2,
0xce, 0x77, 0x2e, 0xf9, 0x11, 0xc4, 0x80, 0x43,
0x5a, 0x73, 0x8b, 0x73, 0xdd, 0xf0, 0x54, 0x44,
0x7c, 0x56, 0x19, 0x54, 0xda,
},
}
 
var aesServerScript = [][]byte{
{
0x16, 0x03, 0x02, 0x00, 0x7f, 0x01, 0x00, 0x00,
0x7b, 0x03, 0x02, 0x4d, 0x08, 0x2d, 0x0b, 0xb3,
0x57, 0x85, 0x71, 0x4b, 0xfb, 0x34, 0xab, 0x16,
0xd4, 0x92, 0x50, 0x81, 0x16, 0x95, 0x11, 0x28,
0x1a, 0xcb, 0xff, 0x09, 0x4d, 0x23, 0xa6, 0xfe,
0x2e, 0xbb, 0x78, 0x00, 0x00, 0x34, 0x00, 0x33,
0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
0x00, 0x8a, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x09,
0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0xff,
0x01, 0x00, 0x01, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x16,
0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e,
0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0x71, 0x9c, 0xe7, 0x23, 0xfc,
0xb9, 0x19, 0x29, 0x82, 0xbf, 0xef, 0x08, 0xf7,
0x99, 0x36, 0xc3, 0x4c, 0x6f, 0x05, 0xd2, 0x8b,
0x62, 0x2b, 0x19, 0x9b, 0x7f, 0xc0, 0xcc, 0x48,
0x30, 0x5f, 0xcd, 0xc3, 0x70, 0x55, 0x53, 0x73,
0xfa, 0x79, 0x74, 0xf3, 0xa3, 0x76, 0x9f, 0xa1,
0x7f, 0x98, 0xc2, 0xc0, 0xe3, 0xc5, 0xa0, 0x31,
0x2f, 0xa6, 0xe8, 0x1e, 0x61, 0x46, 0xb3, 0x9b,
0x4b, 0x16, 0xf1, 0x2d, 0xc7, 0x63, 0x7f, 0x79,
0x22, 0x30, 0xd1, 0xf2, 0xfc, 0x77, 0x98, 0x0a,
0x16, 0x11, 0x63, 0x71, 0x7f, 0x70, 0xef, 0x16,
0xbb, 0x39, 0x87, 0x34, 0xac, 0x49, 0xbd, 0x07,
0x67, 0xcb, 0x9c, 0xcc, 0xde, 0xef, 0xb1, 0xe0,
0xdb, 0x01, 0xb5, 0x35, 0xa9, 0xb3, 0x10, 0x0c,
0x4b, 0xee, 0xb3, 0x4e, 0xfd, 0xbe, 0x15, 0x27,
0xf0, 0x46, 0xb2, 0x38, 0xba, 0x5f, 0xcc, 0x89,
0xec, 0x29, 0x82, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x3c, 0xfb,
0xa4, 0x12, 0xcb, 0x00, 0xf9, 0x57, 0x7e, 0x9b,
0xc9, 0xdc, 0x0c, 0xba, 0x9a, 0x81, 0x62, 0xfb,
0x26, 0x13, 0x53, 0xfe, 0xaa, 0xcc, 0x82, 0xbb,
0xb6, 0x67, 0x7f, 0x39, 0xbe, 0x4d, 0xbb, 0xc0,
0x6c, 0x24, 0x31, 0x83, 0xa5, 0x50, 0x3a, 0x75,
0x32, 0x64, 0xb5, 0xdb, 0xbe, 0x0a,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x30, 0x43, 0x24, 0x42, 0x55, 0x08,
0xe4, 0xc2, 0x15, 0xc9, 0xdb, 0x71, 0x69, 0xee,
0x09, 0xc5, 0x1c, 0xfd, 0x46, 0x10, 0xa0, 0x68,
0x21, 0xf2, 0x48, 0xac, 0x6c, 0xc0, 0x2b, 0x62,
0x07, 0x8f, 0x48, 0x33, 0x0a, 0x6b, 0x62, 0x28,
0x2e, 0x2c, 0xad, 0xcb, 0x34, 0x85, 0xca, 0x2e,
0xcd, 0x84, 0xf0,
},
}
 
var sslv3ServerScript = [][]byte{
{
0x16, 0x03, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00,
0x3d, 0x03, 0x00, 0x4e, 0x70, 0xe2, 0x18, 0x86,
0xd6, 0xc6, 0x6f, 0xf3, 0xc8, 0xf4, 0x02, 0xd6,
0x4d, 0xee, 0x17, 0x32, 0x4b, 0xd2, 0x78, 0xd8,
0xa1, 0x03, 0x5d, 0x68, 0x82, 0x89, 0xbe, 0xfd,
0x12, 0xb9, 0x06, 0x00, 0x00, 0x16, 0x00, 0x33,
0x00, 0x39, 0x00, 0x16, 0x00, 0x32, 0x00, 0x38,
0x00, 0x13, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
0x00, 0x05, 0x00, 0x04, 0x01, 0x00,
},
 
{
0x16, 0x03, 0x00, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
0x03, 0x00, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x00, 0x00, 0x04, 0x0e,
0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00,
0x80, 0x74, 0x0e, 0x3a, 0xcf, 0xba, 0x9f, 0x1a,
0x9b, 0xb2, 0xa4, 0xc7, 0x5d, 0xf3, 0x0c, 0x80,
0x06, 0x80, 0xf3, 0x57, 0xb2, 0xd9, 0x36, 0x24,
0x6a, 0x06, 0x13, 0x40, 0xf9, 0x7c, 0xb9, 0x3e,
0x4b, 0x68, 0x4f, 0x21, 0x90, 0x2d, 0xbd, 0xca,
0xd4, 0x83, 0xf0, 0x7a, 0xeb, 0x7a, 0x74, 0x1b,
0xcd, 0xfe, 0x69, 0xef, 0xc0, 0x86, 0xa0, 0x24,
0x31, 0x65, 0x40, 0xd2, 0xdd, 0x6f, 0xb9, 0xd7,
0x8d, 0xc1, 0x69, 0x60, 0x44, 0x7a, 0x75, 0xfb,
0x42, 0x6a, 0x0f, 0x66, 0x45, 0x10, 0x73, 0xee,
0x87, 0x28, 0x37, 0x83, 0x86, 0xd8, 0x5a, 0xc8,
0x60, 0x87, 0xda, 0x33, 0x87, 0xaf, 0x34, 0x8b,
0xf5, 0x61, 0x63, 0x7a, 0x5c, 0x60, 0x26, 0xb9,
0xdb, 0xa1, 0xb7, 0xe3, 0x60, 0x38, 0x94, 0x5c,
0x83, 0x23, 0xd6, 0x8d, 0xc2, 0x14, 0x4a, 0x0f,
0x0e, 0x4f, 0xf9, 0x4e, 0x7b, 0x15, 0xcd, 0x18,
0x04, 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16,
0x03, 0x00, 0x00, 0x3c, 0xbd, 0xbc, 0xec, 0xdc,
0x79, 0xb1, 0xae, 0x16, 0xc9, 0x26, 0x9a, 0xc0,
0xc0, 0x2c, 0x33, 0x36, 0x13, 0x91, 0x58, 0x5d,
0x7d, 0xee, 0x4e, 0xd8, 0x7e, 0xac, 0x88, 0x87,
0x0a, 0x75, 0x66, 0xb1, 0x44, 0x79, 0x2f, 0x42,
0xe8, 0x92, 0x74, 0x4c, 0xab, 0x36, 0xc8, 0x17,
0x5f, 0x02, 0x8a, 0x20, 0x53, 0xe9, 0x1d, 0xb4,
0xfe, 0x5c, 0x2b, 0xd9, 0x0a, 0xfb, 0xc6, 0x63,
},
 
{
0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, 0x03,
0x00, 0x00, 0x3c, 0xaa, 0xa1, 0x98, 0xc4, 0x6b,
0x5a, 0x16, 0x3f, 0x5f, 0xa4, 0x96, 0x3e, 0x78,
0xe4, 0x6f, 0x49, 0x05, 0x47, 0xc4, 0x05, 0x60,
0xeb, 0x0b, 0x45, 0xe3, 0xbc, 0x50, 0x11, 0x24,
0x5f, 0x01, 0xd7, 0xb8, 0x8f, 0x60, 0x63, 0x66,
0xbd, 0x3e, 0xd9, 0xa8, 0x80, 0x43, 0x9f, 0x0b,
0x51, 0x61, 0xed, 0x13, 0xc6, 0x21, 0xd0, 0xfe,
0xbc, 0x17, 0x3c, 0x36, 0xb0, 0x82, 0x7f, 0x17,
0x03, 0x00, 0x00, 0x21, 0xee, 0x44, 0xf3, 0xa6,
0x88, 0x9d, 0x78, 0x44, 0xde, 0xdf, 0xeb, 0xc5,
0xad, 0xc4, 0xcc, 0x56, 0x5c, 0x54, 0x96, 0x52,
0x3f, 0xd9, 0x40, 0x6e, 0x79, 0xd8, 0x58, 0x78,
0x4f, 0x5a, 0xe9, 0x06, 0xef, 0x15, 0x03, 0x00,
0x00, 0x16, 0xd3, 0xc2, 0x52, 0x99, 0x2a, 0x84,
0xc4, 0x52, 0x5f, 0x3b, 0x19, 0xe7, 0xfc, 0x65,
0xaf, 0xd3, 0xb7, 0xa3, 0xcc, 0x4a, 0x1d, 0x2e,
},
}
 
var clientauthTests = []clientauthTest{
// Server doesn't asks for cert
// gotest -test.run "TestRunServer" -serve -clientauth 0
// gnutls-cli --insecure --debug 100 -p 10443 localhost 2>&1 |
// python parse-gnutls-cli-debug-log.py
{"NoClientCert", NoClientCert, nil,
[][]byte{{
0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
0x76, 0x03, 0x02, 0x4e, 0xe0, 0x92, 0x5d, 0xcd,
0xfe, 0x0c, 0x69, 0xd4, 0x7d, 0x8e, 0xa6, 0x88,
0xde, 0x72, 0x04, 0x29, 0x6a, 0x4a, 0x16, 0x23,
0xd7, 0x8f, 0xbc, 0xfa, 0x80, 0x73, 0x2e, 0x12,
0xb7, 0x0b, 0x39, 0x00, 0x00, 0x34, 0x00, 0x33,
0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e,
0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0x10, 0xe1, 0x00, 0x3d, 0x0a,
0x6b, 0x02, 0x7f, 0x97, 0xde, 0xfb, 0x65, 0x46,
0x1a, 0x50, 0x4e, 0x34, 0x9a, 0xae, 0x14, 0x7e,
0xec, 0xef, 0x85, 0x15, 0x3b, 0x39, 0xc2, 0x45,
0x04, 0x40, 0x92, 0x71, 0xd6, 0x7e, 0xf6, 0xfd,
0x4d, 0x84, 0xf7, 0xc4, 0x77, 0x99, 0x3d, 0xe2,
0xc3, 0x8d, 0xb0, 0x4c, 0x74, 0xc8, 0x51, 0xec,
0xb2, 0xe8, 0x6b, 0xa1, 0xd2, 0x4d, 0xd8, 0x61,
0x92, 0x7a, 0x24, 0x57, 0x44, 0x4f, 0xa2, 0x1e,
0x74, 0x0b, 0x06, 0x4b, 0x80, 0x34, 0x8b, 0xfe,
0xc2, 0x0e, 0xc1, 0xcd, 0xab, 0x0c, 0x3f, 0x54,
0xe2, 0x44, 0xe9, 0x6c, 0x2b, 0xba, 0x7b, 0x64,
0xf1, 0x93, 0x65, 0x75, 0xf2, 0x35, 0xff, 0x27,
0x03, 0xd5, 0x64, 0xe6, 0x8e, 0xe7, 0x7b, 0x56,
0xb6, 0x61, 0x73, 0xeb, 0xa2, 0xdc, 0xa4, 0x6e,
0x52, 0xac, 0xbc, 0xba, 0x11, 0xa3, 0xd2, 0x61,
0x4a, 0xe0, 0xbb, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xd2, 0x5a,
0x0c, 0x2a, 0x27, 0x96, 0xba, 0xa9, 0x67, 0xd2,
0x51, 0x68, 0x32, 0x68, 0x22, 0x1f, 0xb9, 0x27,
0x79, 0x59, 0x28, 0xdf, 0x38, 0x1f, 0x92, 0x21,
0x5d, 0x0f, 0xf4, 0xc0, 0xee, 0xb7, 0x10, 0x5a,
0xa9, 0x45,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x24, 0x13, 0x6f, 0x6c, 0x71, 0x83,
0x59, 0xcf, 0x32, 0x72, 0xe9, 0xce, 0xcc, 0x7a,
0x6c, 0xf0, 0x72, 0x39, 0x16, 0xae, 0x40, 0x61,
0xfa, 0x92, 0x4c, 0xe7, 0xf2, 0x1a, 0xd7, 0x0c,
0x84, 0x76, 0x6c, 0xe9, 0x11, 0x43, 0x19, 0x17,
0x03, 0x01, 0x00, 0x21, 0xc0, 0xa2, 0x13, 0x28,
0x94, 0x8c, 0x5c, 0xd6, 0x79, 0xb9, 0xfe, 0xae,
0x45, 0x4b, 0xc0, 0x7c, 0xae, 0x2d, 0xb4, 0x0d,
0x31, 0xc4, 0xad, 0x22, 0xd7, 0x1e, 0x99, 0x1c,
0x4c, 0x69, 0xab, 0x42, 0x61, 0x15, 0x03, 0x01,
0x00, 0x16, 0xe1, 0x0c, 0x67, 0xf3, 0xf4, 0xb9,
0x8e, 0x81, 0x8e, 0x01, 0xb8, 0xa0, 0x69, 0x8c,
0x03, 0x11, 0x43, 0x3e, 0xee, 0xb7, 0x4d, 0x69,
}}},
// Server asks for cert with empty CA list, client doesn't give it.
// gotest -test.run "TestRunServer" -serve -clientauth 1
// gnutls-cli --insecure --debug 100 -p 10443 localhost
{"RequestClientCert, none given", RequestClientCert, nil,
[][]byte{{
0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
0x76, 0x03, 0x02, 0x4e, 0xe0, 0x93, 0xe2, 0x47,
0x06, 0xa0, 0x61, 0x0c, 0x51, 0xdd, 0xf0, 0xef,
0xf4, 0x30, 0x72, 0xe1, 0xa6, 0x50, 0x68, 0x82,
0x3c, 0xfb, 0xcb, 0x72, 0x5e, 0x73, 0x9d, 0xda,
0x27, 0x35, 0x72, 0x00, 0x00, 0x34, 0x00, 0x33,
0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x08, 0x0d,
0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x16,
0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x07, 0x0b, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, 0x00,
0x86, 0x10, 0x00, 0x00, 0x82, 0x00, 0x80, 0x64,
0x28, 0xb9, 0x3f, 0x48, 0xaf, 0x06, 0x22, 0x39,
0x56, 0xd8, 0x6f, 0x63, 0x5d, 0x03, 0x48, 0x63,
0x01, 0x13, 0xa2, 0xd6, 0x76, 0xc0, 0xab, 0xda,
0x25, 0x30, 0x75, 0x6c, 0xaa, 0xb4, 0xdc, 0x35,
0x72, 0xdc, 0xf2, 0x43, 0xe4, 0x1d, 0x82, 0xfb,
0x6c, 0x64, 0xe2, 0xa7, 0x8f, 0x32, 0x67, 0x6b,
0xcd, 0xd2, 0xb2, 0x36, 0x94, 0xbc, 0x6f, 0x46,
0x79, 0x29, 0x42, 0xe3, 0x1a, 0xbf, 0xfb, 0x41,
0xd5, 0xe3, 0xb4, 0x2a, 0xf6, 0x95, 0x6f, 0x0c,
0x87, 0xb9, 0x03, 0x18, 0xa1, 0xea, 0x4a, 0xe2,
0x2e, 0x0f, 0x50, 0x00, 0xc1, 0xe8, 0x8c, 0xc8,
0xa2, 0xf6, 0xa4, 0x05, 0xf4, 0x38, 0x3e, 0xd9,
0x6e, 0x63, 0x96, 0x0c, 0x34, 0x73, 0x90, 0x03,
0x55, 0xa6, 0x34, 0xb0, 0x5e, 0x8c, 0x48, 0x40,
0x25, 0x45, 0x84, 0xa6, 0x21, 0x3f, 0x81, 0x97,
0xa7, 0x11, 0x09, 0x14, 0x95, 0xa5, 0xe5, 0x14,
0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01,
0x00, 0x24, 0x16, 0xaa, 0x01, 0x2c, 0xa8, 0xc1,
0x28, 0xaf, 0x35, 0xc1, 0xc1, 0xf3, 0x0a, 0x25,
0x66, 0x6e, 0x27, 0x11, 0xa3, 0xa4, 0xd9, 0xe9,
0xea, 0x15, 0x09, 0x9d, 0x28, 0xe3, 0x5b, 0x2b,
0xa6, 0x25, 0xa7, 0x14, 0x24, 0x3a,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x24, 0x9a, 0xa8, 0xd6, 0x77, 0x46,
0x45, 0x68, 0x9d, 0x5d, 0xa9, 0x68, 0x03, 0xe5,
0xaf, 0xe8, 0xc8, 0x21, 0xc5, 0xc6, 0xc1, 0x50,
0xe0, 0xd8, 0x52, 0xce, 0xa3, 0x4f, 0x2d, 0xf4,
0xe3, 0xa7, 0x7d, 0x35, 0x80, 0x84, 0x12, 0x17,
0x03, 0x01, 0x00, 0x21, 0x8a, 0x82, 0x0c, 0x54,
0x1b, 0xeb, 0x77, 0x90, 0x2c, 0x3e, 0xbc, 0xf0,
0x23, 0xcc, 0xa8, 0x9f, 0x25, 0x08, 0x12, 0xed,
0x43, 0xf1, 0xf9, 0x06, 0xad, 0xa9, 0x4b, 0x97,
0x82, 0xb7, 0xc4, 0x0b, 0x4c, 0x15, 0x03, 0x01,
0x00, 0x16, 0x05, 0x2d, 0x9d, 0x45, 0x03, 0xb7,
0xc2, 0xd1, 0xb5, 0x1a, 0x43, 0xcf, 0x1a, 0x37,
0xf4, 0x70, 0xcc, 0xb4, 0xed, 0x07, 0x76, 0x3a,
}}},
// Server asks for cert with empty CA list, client gives one
// gotest -test.run "TestRunServer" -serve -clientauth 1
// gnutls-cli --insecure --debug 100 -p 10443 localhost
{"RequestClientCert, client gives it", RequestClientCert,
[]*x509.Certificate{clicert},
[][]byte{{
0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
0x76, 0x03, 0x02, 0x4e, 0xe7, 0x44, 0xda, 0x58,
0x7d, 0x46, 0x4a, 0x48, 0x97, 0x9f, 0xe5, 0x91,
0x11, 0x64, 0xa7, 0x1e, 0x4d, 0xb7, 0xfe, 0x9b,
0xc6, 0x63, 0xf8, 0xa4, 0xb5, 0x0b, 0x18, 0xb5,
0xbd, 0x19, 0xb3, 0x00, 0x00, 0x34, 0x00, 0x33,
0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
0x00, 0x8a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba,
0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82,
0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0,
0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39,
0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31,
0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30,
0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20,
0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf,
0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b,
0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a,
0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65,
0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4,
0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62,
0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c,
0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58,
0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0,
0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f,
0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18,
0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1,
0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9,
0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01,
0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d,
0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7,
0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad,
0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69,
0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18,
0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1,
0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb,
0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e,
0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09,
0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8,
0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b,
0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0,
0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5,
0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae,
0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e,
0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5,
0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30,
0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7,
0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78,
0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d,
0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75,
0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd,
0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c,
0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57,
0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b,
0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7,
0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x08, 0x0d,
0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x16,
0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x01, 0xfb, 0x0b, 0x00, 0x01,
0xf7, 0x00, 0x01, 0xf4, 0x00, 0x01, 0xf1, 0x30,
0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x58, 0xa0,
0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30,
0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x30, 0x26, 0x31, 0x10,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f,
0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30,
0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d,
0x31, 0x31, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37,
0x35, 0x35, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x31,
0x32, 0x31, 0x32, 0x30, 0x37, 0x30, 0x38, 0x30,
0x30, 0x31, 0x32, 0x5a, 0x30, 0x26, 0x31, 0x10,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f,
0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30,
0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9c, 0x30,
0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x03, 0x81, 0x8c, 0x00,
0x30, 0x81, 0x88, 0x02, 0x81, 0x80, 0x4e, 0xd0,
0x7b, 0x31, 0xe3, 0x82, 0x64, 0xd9, 0x59, 0xc0,
0xc2, 0x87, 0xa4, 0x5e, 0x1e, 0x8b, 0x73, 0x33,
0xc7, 0x63, 0x53, 0xdf, 0x66, 0x92, 0x06, 0x84,
0xf6, 0x64, 0xd5, 0x8f, 0xe4, 0x36, 0xa7, 0x1d,
0x2b, 0xe8, 0xb3, 0x20, 0x36, 0x45, 0x23, 0xb5,
0xe3, 0x95, 0xae, 0xed, 0xe0, 0xf5, 0x20, 0x9c,
0x8d, 0x95, 0xdf, 0x7f, 0x5a, 0x12, 0xef, 0x87,
0xe4, 0x5b, 0x68, 0xe4, 0xe9, 0x0e, 0x74, 0xec,
0x04, 0x8a, 0x7f, 0xde, 0x93, 0x27, 0xc4, 0x01,
0x19, 0x7a, 0xbd, 0xf2, 0xdc, 0x3d, 0x14, 0xab,
0xd0, 0x54, 0xca, 0x21, 0x0c, 0xd0, 0x4d, 0x6e,
0x87, 0x2e, 0x5c, 0xc5, 0xd2, 0xbb, 0x4d, 0x4b,
0x4f, 0xce, 0xb6, 0x2c, 0xf7, 0x7e, 0x88, 0xec,
0x7c, 0xd7, 0x02, 0x91, 0x74, 0xa6, 0x1e, 0x0c,
0x1a, 0xda, 0xe3, 0x4a, 0x5a, 0x2e, 0xde, 0x13,
0x9c, 0x4c, 0x40, 0x88, 0x59, 0x93, 0x02, 0x03,
0x01, 0x00, 0x01, 0xa3, 0x32, 0x30, 0x30, 0x30,
0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0xa0, 0x30,
0x0d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x06,
0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0f,
0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x08, 0x30,
0x06, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30,
0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x03, 0x81, 0x81, 0x00,
0x36, 0x1f, 0xb3, 0x7a, 0x0c, 0x75, 0xc9, 0x6e,
0x37, 0x46, 0x61, 0x2b, 0xd5, 0xbd, 0xc0, 0xa7,
0x4b, 0xcc, 0x46, 0x9a, 0x81, 0x58, 0x7c, 0x85,
0x79, 0x29, 0xc8, 0xc8, 0xc6, 0x67, 0xdd, 0x32,
0x56, 0x45, 0x2b, 0x75, 0xb6, 0xe9, 0x24, 0xa9,
0x50, 0x9a, 0xbe, 0x1f, 0x5a, 0xfa, 0x1a, 0x15,
0xd9, 0xcc, 0x55, 0x95, 0x72, 0x16, 0x83, 0xb9,
0xc2, 0xb6, 0x8f, 0xfd, 0x88, 0x8c, 0x38, 0x84,
0x1d, 0xab, 0x5d, 0x92, 0x31, 0x13, 0x4f, 0xfd,
0x83, 0x3b, 0xc6, 0x9d, 0xf1, 0x11, 0x62, 0xb6,
0x8b, 0xec, 0xab, 0x67, 0xbe, 0xc8, 0x64, 0xb0,
0x11, 0x50, 0x46, 0x58, 0x17, 0x6b, 0x99, 0x1c,
0xd3, 0x1d, 0xfc, 0x06, 0xf1, 0x0e, 0xe5, 0x96,
0xa8, 0x0c, 0xf9, 0x78, 0x20, 0xb7, 0x44, 0x18,
0x51, 0x8d, 0x10, 0x7e, 0x4f, 0x94, 0x67, 0xdf,
0xa3, 0x4e, 0x70, 0x73, 0x8e, 0x90, 0x91, 0x85,
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0xa7, 0x2f, 0xed, 0xfa, 0xc2,
0xbd, 0x46, 0xa1, 0xf2, 0x69, 0xc5, 0x1d, 0xa1,
0x34, 0xd6, 0xd0, 0x84, 0xf5, 0x5d, 0x8c, 0x82,
0x8d, 0x98, 0x82, 0x9c, 0xd9, 0x07, 0xe0, 0xf7,
0x55, 0x49, 0x4d, 0xa1, 0x48, 0x59, 0x02, 0xd3,
0x84, 0x37, 0xaf, 0x01, 0xb3, 0x3a, 0xf4, 0xed,
0x99, 0xbe, 0x67, 0x36, 0x19, 0x55, 0xf3, 0xf9,
0xcb, 0x94, 0xe5, 0x7b, 0x8b, 0x77, 0xf2, 0x5f,
0x4c, 0xfe, 0x01, 0x1f, 0x7b, 0xd7, 0x23, 0x49,
0x0c, 0xcb, 0x6c, 0xb0, 0xe7, 0x77, 0xd6, 0xcf,
0xa8, 0x7d, 0xdb, 0xa7, 0x14, 0xe2, 0xf5, 0xf3,
0xff, 0xba, 0x23, 0xd2, 0x9a, 0x36, 0x14, 0x60,
0x2a, 0x91, 0x5d, 0x2b, 0x35, 0x3b, 0xb6, 0xdd,
0xcb, 0x6b, 0xdc, 0x18, 0xdc, 0x33, 0xb8, 0xb3,
0xc7, 0x27, 0x7e, 0xfc, 0xd2, 0xf7, 0x97, 0x90,
0x5e, 0x17, 0xac, 0x14, 0x8e, 0x0f, 0xca, 0xb5,
0x6f, 0xc9, 0x2d, 0x16, 0x03, 0x01, 0x00, 0x86,
0x0f, 0x00, 0x00, 0x82, 0x00, 0x80, 0x44, 0x7f,
0xa2, 0x59, 0x60, 0x0b, 0x5a, 0xc4, 0xaf, 0x1e,
0x60, 0xa5, 0x24, 0xea, 0xc1, 0xc3, 0x22, 0x21,
0x6b, 0x22, 0x8b, 0x2a, 0x11, 0x82, 0x68, 0x7d,
0xb9, 0xdd, 0x9c, 0x27, 0x4c, 0xc2, 0xc8, 0xa2,
0x8b, 0x6b, 0x77, 0x8d, 0x3a, 0x2b, 0x8d, 0x2f,
0x6a, 0x2b, 0x43, 0xd2, 0xd1, 0xc6, 0x41, 0x79,
0xa2, 0x4f, 0x2b, 0xc2, 0xf7, 0xb2, 0x10, 0xad,
0xa6, 0x01, 0x51, 0x51, 0x25, 0xe7, 0x58, 0x7a,
0xcf, 0x3b, 0xc4, 0x29, 0xb5, 0xe5, 0xa7, 0x83,
0xe6, 0xcb, 0x1e, 0xf3, 0x02, 0x0f, 0x53, 0x3b,
0xb5, 0x39, 0xef, 0x9c, 0x42, 0xe0, 0xa6, 0x9b,
0x2b, 0xdd, 0x60, 0xae, 0x0a, 0x73, 0x35, 0xbe,
0x26, 0x10, 0x1b, 0xe9, 0xe9, 0x61, 0xab, 0x20,
0xa5, 0x48, 0xc6, 0x60, 0xa6, 0x50, 0x3c, 0xfb,
0xa7, 0xca, 0xb0, 0x80, 0x95, 0x1e, 0xce, 0xc7,
0xbb, 0x68, 0x44, 0xdc, 0x0e, 0x0e, 0x14, 0x03,
0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00,
0x24, 0xb6, 0xcd, 0x0c, 0x78, 0xfd, 0xd6, 0xff,
0xbe, 0x97, 0xd5, 0x0a, 0x7d, 0x4f, 0xa1, 0x03,
0x78, 0xc8, 0x61, 0x6f, 0xf2, 0x4b, 0xa8, 0x56,
0x4f, 0x3c, 0xa2, 0xd9, 0xd0, 0x20, 0x13, 0x1b,
0x8b, 0x36, 0xb7, 0x33, 0x9c,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x24, 0xa3, 0x43, 0x94, 0xe7, 0xdf,
0xb6, 0xc3, 0x03, 0x9f, 0xc1, 0x59, 0x0c, 0xc3,
0x13, 0xae, 0xed, 0xcf, 0xff, 0xf1, 0x80, 0xf3,
0x13, 0x63, 0x1c, 0xf0, 0xca, 0xad, 0x9e, 0x71,
0x46, 0x5f, 0x6b, 0xeb, 0x10, 0x3f, 0xe3, 0x17,
0x03, 0x01, 0x00, 0x21, 0xe9, 0x80, 0x95, 0x6e,
0x05, 0x55, 0x2f, 0xed, 0x4d, 0xde, 0x17, 0x3a,
0x32, 0x9b, 0x2a, 0x74, 0x30, 0x4f, 0xe0, 0x9f,
0x4e, 0xd3, 0x06, 0xbd, 0x3a, 0x43, 0x75, 0x8b,
0x5b, 0x9a, 0xd8, 0x2e, 0x56, 0x15, 0x03, 0x01,
0x00, 0x16, 0x53, 0xf5, 0xff, 0xe0, 0xa1, 0x6c,
0x33, 0xf4, 0x4e, 0x89, 0x68, 0xe1, 0xf7, 0x61,
0x13, 0xb3, 0x12, 0xa1, 0x8e, 0x5a, 0x7a, 0x02,
}}},
}
 
// cert.pem and key.pem were generated with generate_cert.go
// Thus, they have no ExtKeyUsage fields and trigger an error
// when verification is turned on.
 
var clicert = loadPEMCert(`
-----BEGIN CERTIFICATE-----
MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc
MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG
hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE
ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e
E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw
DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A
p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4
hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE
GFGNEH5PlGffo05wc46QkYU=
-----END CERTIFICATE-----
`)
 
/* corresponding key.pem for cert.pem is:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgE7QezHjgmTZWcDCh6ReHotzM8djU99mkgaE9mTVj+Q2px0r6LMg
NkUjteOVru3g9SCcjZXff1oS74fkW2jk6Q507ASKf96TJ8QBGXq98tw9FKvQVMoh
DNBNbocuXMXSu01LT862LPd+iOx81wKRdKYeDBra40paLt4TnExAiFmTAgMBAAEC
gYBxvXd8yNteFTns8A/2yomEMC4yeosJJSpp1CsN3BJ7g8/qTnrVPxBy+RU+qr63
t2WquaOu/cr5P8iEsa6lk20tf8pjKLNXeX0b1RTzK8rJLbS7nGzP3tvOhL096VtQ
dAo4ROEaro0TzYpHmpciSvxVIeEIAAdFDObDJPKqcJAxyQJBAJizfYgK8Gzx9fsx
hxp+VteCbVPg2euASH5Yv3K5LukRdKoSzHE2grUVQgN/LafC0eZibRanxHegYSr7
7qaswKUCQQCEIWor/X4XTMdVj3Oj+vpiw75y/S9gh682+myZL+d/02IEkwnB098P
RkKVpenBHyrGg0oeN5La7URILWKj7CPXAkBKo6F+d+phNjwIFoN1Xb/RA32w/D1I
saG9sF+UEhRt9AxUfW/U/tIQ9V0ZHHcSg1XaCM5Nvp934brdKdvTOKnJAkBD5h/3
Rybatlvg/fzBEaJFyq09zhngkxlZOUtBVTqzl17RVvY2orgH02U4HbCHy4phxOn7
qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN
1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvAMAA=
-----END RSA PRIVATE KEY-----
*/
/tls/handshake_messages_test.go
0,0 → 1,209
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"math/rand"
"reflect"
"testing"
"testing/quick"
)
 
var tests = []interface{}{
&clientHelloMsg{},
&serverHelloMsg{},
&finishedMsg{},
 
&certificateMsg{},
&certificateRequestMsg{},
&certificateVerifyMsg{},
&certificateStatusMsg{},
&clientKeyExchangeMsg{},
&nextProtoMsg{},
}
 
type testMessage interface {
marshal() []byte
unmarshal([]byte) bool
equal(interface{}) bool
}
 
func TestMarshalUnmarshal(t *testing.T) {
rand := rand.New(rand.NewSource(0))
 
for i, iface := range tests {
ty := reflect.ValueOf(iface).Type()
 
n := 100
if testing.Short() {
n = 5
}
for j := 0; j < n; j++ {
v, ok := quick.Value(ty, rand)
if !ok {
t.Errorf("#%d: failed to create value", i)
break
}
 
m1 := v.Interface().(testMessage)
marshaled := m1.marshal()
m2 := iface.(testMessage)
if !m2.unmarshal(marshaled) {
t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
break
}
m2.marshal() // to fill any marshal cache in the message
 
if !m1.equal(m2) {
t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
break
}
 
if i >= 3 {
// The first three message types (ClientHello,
// ServerHello and Finished) are allowed to
// have parsable prefixes because the extension
// data is optional and the length of the
// Finished varies across versions.
for j := 0; j < len(marshaled); j++ {
if m2.unmarshal(marshaled[0:j]) {
t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
break
}
}
}
}
}
}
 
func TestFuzz(t *testing.T) {
rand := rand.New(rand.NewSource(0))
for _, iface := range tests {
m := iface.(testMessage)
 
for j := 0; j < 1000; j++ {
len := rand.Intn(100)
bytes := randomBytes(len, rand)
// This just looks for crashes due to bounds errors etc.
m.unmarshal(bytes)
}
}
}
 
func randomBytes(n int, rand *rand.Rand) []byte {
r := make([]byte, n)
for i := 0; i < n; i++ {
r[i] = byte(rand.Int31())
}
return r
}
 
func randomString(n int, rand *rand.Rand) string {
b := randomBytes(n, rand)
return string(b)
}
 
func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &clientHelloMsg{}
m.vers = uint16(rand.Intn(65536))
m.random = randomBytes(32, rand)
m.sessionId = randomBytes(rand.Intn(32), rand)
m.cipherSuites = make([]uint16, rand.Intn(63)+1)
for i := 0; i < len(m.cipherSuites); i++ {
m.cipherSuites[i] = uint16(rand.Int31())
}
m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
if rand.Intn(10) > 5 {
m.nextProtoNeg = true
}
if rand.Intn(10) > 5 {
m.serverName = randomString(rand.Intn(255), rand)
}
m.ocspStapling = rand.Intn(10) > 5
m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
m.supportedCurves = make([]uint16, rand.Intn(5)+1)
for i := range m.supportedCurves {
m.supportedCurves[i] = uint16(rand.Intn(30000))
}
 
return reflect.ValueOf(m)
}
 
func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &serverHelloMsg{}
m.vers = uint16(rand.Intn(65536))
m.random = randomBytes(32, rand)
m.sessionId = randomBytes(rand.Intn(32), rand)
m.cipherSuite = uint16(rand.Int31())
m.compressionMethod = uint8(rand.Intn(256))
 
if rand.Intn(10) > 5 {
m.nextProtoNeg = true
 
n := rand.Intn(10)
m.nextProtos = make([]string, n)
for i := 0; i < n; i++ {
m.nextProtos[i] = randomString(20, rand)
}
}
 
return reflect.ValueOf(m)
}
 
func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &certificateMsg{}
numCerts := rand.Intn(20)
m.certificates = make([][]byte, numCerts)
for i := 0; i < numCerts; i++ {
m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
}
return reflect.ValueOf(m)
}
 
func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &certificateRequestMsg{}
m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
numCAs := rand.Intn(100)
m.certificateAuthorities = make([][]byte, numCAs)
for i := 0; i < numCAs; i++ {
m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand)
}
return reflect.ValueOf(m)
}
 
func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &certificateVerifyMsg{}
m.signature = randomBytes(rand.Intn(15)+1, rand)
return reflect.ValueOf(m)
}
 
func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &certificateStatusMsg{}
if rand.Intn(10) > 5 {
m.statusType = statusTypeOCSP
m.response = randomBytes(rand.Intn(10)+1, rand)
} else {
m.statusType = 42
}
return reflect.ValueOf(m)
}
 
func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &clientKeyExchangeMsg{}
m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
return reflect.ValueOf(m)
}
 
func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &finishedMsg{}
m.verifyData = randomBytes(12, rand)
return reflect.ValueOf(m)
}
 
func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &nextProtoMsg{}
m.proto = randomString(rand.Intn(255), rand)
return reflect.ValueOf(m)
}
/tls/handshake_server.go
0,0 → 1,349
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"crypto"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
"errors"
"io"
)
 
func (c *Conn) serverHandshake() error {
config := c.config
msg, err := c.readHandshake()
if err != nil {
return err
}
clientHello, ok := msg.(*clientHelloMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
vers, ok := mutualVersion(clientHello.vers)
if !ok {
return c.sendAlert(alertProtocolVersion)
}
c.vers = vers
c.haveVers = true
 
finishedHash := newFinishedHash(vers)
finishedHash.Write(clientHello.marshal())
 
hello := new(serverHelloMsg)
 
supportedCurve := false
Curves:
for _, curve := range clientHello.supportedCurves {
switch curve {
case curveP256, curveP384, curveP521:
supportedCurve = true
break Curves
}
}
 
supportedPointFormat := false
for _, pointFormat := range clientHello.supportedPoints {
if pointFormat == pointFormatUncompressed {
supportedPointFormat = true
break
}
}
 
ellipticOk := supportedCurve && supportedPointFormat
 
var suite *cipherSuite
FindCipherSuite:
for _, id := range clientHello.cipherSuites {
for _, supported := range config.cipherSuites() {
if id == supported {
suite = nil
for _, s := range cipherSuites {
if s.id == id {
suite = s
break
}
}
if suite == nil {
continue
}
// Don't select a ciphersuite which we can't
// support for this client.
if suite.elliptic && !ellipticOk {
continue
}
break FindCipherSuite
}
}
}
 
foundCompression := false
// We only support null compression, so check that the client offered it.
for _, compression := range clientHello.compressionMethods {
if compression == compressionNone {
foundCompression = true
break
}
}
 
if suite == nil || !foundCompression {
return c.sendAlert(alertHandshakeFailure)
}
 
hello.vers = vers
hello.cipherSuite = suite.id
t := uint32(config.time().Unix())
hello.random = make([]byte, 32)
hello.random[0] = byte(t >> 24)
hello.random[1] = byte(t >> 16)
hello.random[2] = byte(t >> 8)
hello.random[3] = byte(t)
_, err = io.ReadFull(config.rand(), hello.random[4:])
if err != nil {
return c.sendAlert(alertInternalError)
}
hello.compressionMethod = compressionNone
if clientHello.nextProtoNeg {
hello.nextProtoNeg = true
hello.nextProtos = config.NextProtos
}
if clientHello.ocspStapling && len(config.Certificates[0].OCSPStaple) > 0 {
hello.ocspStapling = true
}
 
finishedHash.Write(hello.marshal())
c.writeRecord(recordTypeHandshake, hello.marshal())
 
if len(config.Certificates) == 0 {
return c.sendAlert(alertInternalError)
}
 
certMsg := new(certificateMsg)
if len(clientHello.serverName) > 0 {
c.serverName = clientHello.serverName
certMsg.certificates = config.getCertificateForName(clientHello.serverName).Certificate
} else {
certMsg.certificates = config.Certificates[0].Certificate
}
finishedHash.Write(certMsg.marshal())
c.writeRecord(recordTypeHandshake, certMsg.marshal())
 
if hello.ocspStapling {
certStatus := new(certificateStatusMsg)
certStatus.statusType = statusTypeOCSP
certStatus.response = config.Certificates[0].OCSPStaple
finishedHash.Write(certStatus.marshal())
c.writeRecord(recordTypeHandshake, certStatus.marshal())
}
 
keyAgreement := suite.ka()
skx, err := keyAgreement.generateServerKeyExchange(config, clientHello, hello)
if err != nil {
c.sendAlert(alertHandshakeFailure)
return err
}
if skx != nil {
finishedHash.Write(skx.marshal())
c.writeRecord(recordTypeHandshake, skx.marshal())
}
 
if config.ClientAuth >= RequestClientCert {
// Request a client certificate
certReq := new(certificateRequestMsg)
certReq.certificateTypes = []byte{certTypeRSASign}
 
// An empty list of certificateAuthorities signals to
// the client that it may send any certificate in response
// to our request. When we know the CAs we trust, then
// we can send them down, so that the client can choose
// an appropriate certificate to give to us.
if config.ClientCAs != nil {
certReq.certificateAuthorities = config.ClientCAs.Subjects()
}
finishedHash.Write(certReq.marshal())
c.writeRecord(recordTypeHandshake, certReq.marshal())
}
 
helloDone := new(serverHelloDoneMsg)
finishedHash.Write(helloDone.marshal())
c.writeRecord(recordTypeHandshake, helloDone.marshal())
 
var pub *rsa.PublicKey // public key for client auth, if any
 
msg, err = c.readHandshake()
if err != nil {
return err
}
 
// If we requested a client certificate, then the client must send a
// certificate message, even if it's empty.
if config.ClientAuth >= RequestClientCert {
if certMsg, ok = msg.(*certificateMsg); !ok {
return c.sendAlert(alertHandshakeFailure)
}
finishedHash.Write(certMsg.marshal())
 
if len(certMsg.certificates) == 0 {
// The client didn't actually send a certificate
switch config.ClientAuth {
case RequireAnyClientCert, RequireAndVerifyClientCert:
c.sendAlert(alertBadCertificate)
return errors.New("tls: client didn't provide a certificate")
}
}
 
certs := make([]*x509.Certificate, len(certMsg.certificates))
for i, asn1Data := range certMsg.certificates {
if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
c.sendAlert(alertBadCertificate)
return errors.New("tls: failed to parse client certificate: " + err.Error())
}
}
 
if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
opts := x509.VerifyOptions{
Roots: c.config.ClientCAs,
CurrentTime: c.config.time(),
Intermediates: x509.NewCertPool(),
}
 
for i, cert := range certs {
if i == 0 {
continue
}
opts.Intermediates.AddCert(cert)
}
 
chains, err := certs[0].Verify(opts)
if err != nil {
c.sendAlert(alertBadCertificate)
return errors.New("tls: failed to verify client's certificate: " + err.Error())
}
 
ok := false
for _, ku := range certs[0].ExtKeyUsage {
if ku == x509.ExtKeyUsageClientAuth {
ok = true
break
}
}
if !ok {
c.sendAlert(alertHandshakeFailure)
return errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
}
 
c.verifiedChains = chains
}
 
if len(certs) > 0 {
if pub, ok = certs[0].PublicKey.(*rsa.PublicKey); !ok {
return c.sendAlert(alertUnsupportedCertificate)
}
c.peerCertificates = certs
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
}
 
// Get client key exchange
ckx, ok := msg.(*clientKeyExchangeMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
finishedHash.Write(ckx.marshal())
 
// If we received a client cert in response to our certificate request message,
// the client will send us a certificateVerifyMsg immediately after the
// clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preceding
// handshake-layer messages that is signed using the private key corresponding
// to the client's certificate. This allows us to verify that the client is in
// possession of the private key of the certificate.
if len(c.peerCertificates) > 0 {
msg, err = c.readHandshake()
if err != nil {
return err
}
certVerify, ok := msg.(*certificateVerifyMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
 
digest := make([]byte, 0, 36)
digest = finishedHash.serverMD5.Sum(digest)
digest = finishedHash.serverSHA1.Sum(digest)
err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature)
if err != nil {
c.sendAlert(alertBadCertificate)
return errors.New("could not validate signature of connection nonces: " + err.Error())
}
 
finishedHash.Write(certVerify.marshal())
}
 
preMasterSecret, err := keyAgreement.processClientKeyExchange(config, ckx, c.vers)
if err != nil {
c.sendAlert(alertHandshakeFailure)
return err
}
 
masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
keysFromPreMasterSecret(c.vers, preMasterSecret, clientHello.random, hello.random, suite.macLen, suite.keyLen, suite.ivLen)
 
clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */ )
clientHash := suite.mac(c.vers, clientMAC)
c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
c.readRecord(recordTypeChangeCipherSpec)
if err := c.error(); err != nil {
return err
}
 
if hello.nextProtoNeg {
msg, err = c.readHandshake()
if err != nil {
return err
}
nextProto, ok := msg.(*nextProtoMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
finishedHash.Write(nextProto.marshal())
c.clientProtocol = nextProto.proto
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
clientFinished, ok := msg.(*finishedMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
 
verify := finishedHash.clientSum(masterSecret)
if len(verify) != len(clientFinished.verifyData) ||
subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
return c.sendAlert(alertHandshakeFailure)
}
 
finishedHash.Write(clientFinished.marshal())
 
serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */ )
serverHash := suite.mac(c.vers, serverMAC)
c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
 
finished := new(finishedMsg)
finished.verifyData = finishedHash.serverSum(masterSecret)
c.writeRecord(recordTypeHandshake, finished.marshal())
 
c.handshakeComplete = true
c.cipherSuite = suite.id
 
return nil
}
/tls/handshake_messages.go
0,0 → 1,1067
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import "bytes"
 
type clientHelloMsg struct {
raw []byte
vers uint16
random []byte
sessionId []byte
cipherSuites []uint16
compressionMethods []uint8
nextProtoNeg bool
serverName string
ocspStapling bool
supportedCurves []uint16
supportedPoints []uint8
}
 
func (m *clientHelloMsg) equal(i interface{}) bool {
m1, ok := i.(*clientHelloMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
m.vers == m1.vers &&
bytes.Equal(m.random, m1.random) &&
bytes.Equal(m.sessionId, m1.sessionId) &&
eqUint16s(m.cipherSuites, m1.cipherSuites) &&
bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
m.nextProtoNeg == m1.nextProtoNeg &&
m.serverName == m1.serverName &&
m.ocspStapling == m1.ocspStapling &&
eqUint16s(m.supportedCurves, m1.supportedCurves) &&
bytes.Equal(m.supportedPoints, m1.supportedPoints)
}
 
func (m *clientHelloMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
 
length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
numExtensions := 0
extensionsLength := 0
if m.nextProtoNeg {
numExtensions++
}
if m.ocspStapling {
extensionsLength += 1 + 2 + 2
numExtensions++
}
if len(m.serverName) > 0 {
extensionsLength += 5 + len(m.serverName)
numExtensions++
}
if len(m.supportedCurves) > 0 {
extensionsLength += 2 + 2*len(m.supportedCurves)
numExtensions++
}
if len(m.supportedPoints) > 0 {
extensionsLength += 1 + len(m.supportedPoints)
numExtensions++
}
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
}
 
x := make([]byte, 4+length)
x[0] = typeClientHello
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
x[4] = uint8(m.vers >> 8)
x[5] = uint8(m.vers)
copy(x[6:38], m.random)
x[38] = uint8(len(m.sessionId))
copy(x[39:39+len(m.sessionId)], m.sessionId)
y := x[39+len(m.sessionId):]
y[0] = uint8(len(m.cipherSuites) >> 7)
y[1] = uint8(len(m.cipherSuites) << 1)
for i, suite := range m.cipherSuites {
y[2+i*2] = uint8(suite >> 8)
y[3+i*2] = uint8(suite)
}
z := y[2+len(m.cipherSuites)*2:]
z[0] = uint8(len(m.compressionMethods))
copy(z[1:], m.compressionMethods)
 
z = z[1+len(m.compressionMethods):]
if numExtensions > 0 {
z[0] = byte(extensionsLength >> 8)
z[1] = byte(extensionsLength)
z = z[2:]
}
if m.nextProtoNeg {
z[0] = byte(extensionNextProtoNeg >> 8)
z[1] = byte(extensionNextProtoNeg)
// The length is always 0
z = z[4:]
}
if len(m.serverName) > 0 {
z[0] = byte(extensionServerName >> 8)
z[1] = byte(extensionServerName)
l := len(m.serverName) + 5
z[2] = byte(l >> 8)
z[3] = byte(l)
z = z[4:]
 
// RFC 3546, section 3.1
//
// struct {
// NameType name_type;
// select (name_type) {
// case host_name: HostName;
// } name;
// } ServerName;
//
// enum {
// host_name(0), (255)
// } NameType;
//
// opaque HostName<1..2^16-1>;
//
// struct {
// ServerName server_name_list<1..2^16-1>
// } ServerNameList;
 
z[0] = byte((len(m.serverName) + 3) >> 8)
z[1] = byte(len(m.serverName) + 3)
z[3] = byte(len(m.serverName) >> 8)
z[4] = byte(len(m.serverName))
copy(z[5:], []byte(m.serverName))
z = z[l:]
}
if m.ocspStapling {
// RFC 4366, section 3.6
z[0] = byte(extensionStatusRequest >> 8)
z[1] = byte(extensionStatusRequest)
z[2] = 0
z[3] = 5
z[4] = 1 // OCSP type
// Two zero valued uint16s for the two lengths.
z = z[9:]
}
if len(m.supportedCurves) > 0 {
// http://tools.ietf.org/html/rfc4492#section-5.5.1
z[0] = byte(extensionSupportedCurves >> 8)
z[1] = byte(extensionSupportedCurves)
l := 2 + 2*len(m.supportedCurves)
z[2] = byte(l >> 8)
z[3] = byte(l)
l -= 2
z[4] = byte(l >> 8)
z[5] = byte(l)
z = z[6:]
for _, curve := range m.supportedCurves {
z[0] = byte(curve >> 8)
z[1] = byte(curve)
z = z[2:]
}
}
if len(m.supportedPoints) > 0 {
// http://tools.ietf.org/html/rfc4492#section-5.5.2
z[0] = byte(extensionSupportedPoints >> 8)
z[1] = byte(extensionSupportedPoints)
l := 1 + len(m.supportedPoints)
z[2] = byte(l >> 8)
z[3] = byte(l)
l--
z[4] = byte(l)
z = z[5:]
for _, pointFormat := range m.supportedPoints {
z[0] = byte(pointFormat)
z = z[1:]
}
}
 
m.raw = x
 
return x
}
 
func (m *clientHelloMsg) unmarshal(data []byte) bool {
if len(data) < 42 {
return false
}
m.raw = data
m.vers = uint16(data[4])<<8 | uint16(data[5])
m.random = data[6:38]
sessionIdLen := int(data[38])
if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
return false
}
m.sessionId = data[39 : 39+sessionIdLen]
data = data[39+sessionIdLen:]
if len(data) < 2 {
return false
}
// cipherSuiteLen is the number of bytes of cipher suite numbers. Since
// they are uint16s, the number must be even.
cipherSuiteLen := int(data[0])<<8 | int(data[1])
if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
return false
}
numCipherSuites := cipherSuiteLen / 2
m.cipherSuites = make([]uint16, numCipherSuites)
for i := 0; i < numCipherSuites; i++ {
m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
}
data = data[2+cipherSuiteLen:]
if len(data) < 1 {
return false
}
compressionMethodsLen := int(data[0])
if len(data) < 1+compressionMethodsLen {
return false
}
m.compressionMethods = data[1 : 1+compressionMethodsLen]
 
data = data[1+compressionMethodsLen:]
 
m.nextProtoNeg = false
m.serverName = ""
m.ocspStapling = false
 
if len(data) == 0 {
// ClientHello is optionally followed by extension data
return true
}
if len(data) < 2 {
return false
}
 
extensionsLength := int(data[0])<<8 | int(data[1])
data = data[2:]
if extensionsLength != len(data) {
return false
}
 
for len(data) != 0 {
if len(data) < 4 {
return false
}
extension := uint16(data[0])<<8 | uint16(data[1])
length := int(data[2])<<8 | int(data[3])
data = data[4:]
if len(data) < length {
return false
}
 
switch extension {
case extensionServerName:
if length < 2 {
return false
}
numNames := int(data[0])<<8 | int(data[1])
d := data[2:]
for i := 0; i < numNames; i++ {
if len(d) < 3 {
return false
}
nameType := d[0]
nameLen := int(d[1])<<8 | int(d[2])
d = d[3:]
if len(d) < nameLen {
return false
}
if nameType == 0 {
m.serverName = string(d[0:nameLen])
break
}
d = d[nameLen:]
}
case extensionNextProtoNeg:
if length > 0 {
return false
}
m.nextProtoNeg = true
case extensionStatusRequest:
m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
case extensionSupportedCurves:
// http://tools.ietf.org/html/rfc4492#section-5.5.1
if length < 2 {
return false
}
l := int(data[0])<<8 | int(data[1])
if l%2 == 1 || length != l+2 {
return false
}
numCurves := l / 2
m.supportedCurves = make([]uint16, numCurves)
d := data[2:]
for i := 0; i < numCurves; i++ {
m.supportedCurves[i] = uint16(d[0])<<8 | uint16(d[1])
d = d[2:]
}
case extensionSupportedPoints:
// http://tools.ietf.org/html/rfc4492#section-5.5.2
if length < 1 {
return false
}
l := int(data[0])
if length != l+1 {
return false
}
m.supportedPoints = make([]uint8, l)
copy(m.supportedPoints, data[1:])
}
data = data[length:]
}
 
return true
}
 
type serverHelloMsg struct {
raw []byte
vers uint16
random []byte
sessionId []byte
cipherSuite uint16
compressionMethod uint8
nextProtoNeg bool
nextProtos []string
ocspStapling bool
}
 
func (m *serverHelloMsg) equal(i interface{}) bool {
m1, ok := i.(*serverHelloMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
m.vers == m1.vers &&
bytes.Equal(m.random, m1.random) &&
bytes.Equal(m.sessionId, m1.sessionId) &&
m.cipherSuite == m1.cipherSuite &&
m.compressionMethod == m1.compressionMethod &&
m.nextProtoNeg == m1.nextProtoNeg &&
eqStrings(m.nextProtos, m1.nextProtos) &&
m.ocspStapling == m1.ocspStapling
}
 
func (m *serverHelloMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
 
length := 38 + len(m.sessionId)
numExtensions := 0
extensionsLength := 0
 
nextProtoLen := 0
if m.nextProtoNeg {
numExtensions++
for _, v := range m.nextProtos {
nextProtoLen += len(v)
}
nextProtoLen += len(m.nextProtos)
extensionsLength += nextProtoLen
}
if m.ocspStapling {
numExtensions++
}
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
}
 
x := make([]byte, 4+length)
x[0] = typeServerHello
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
x[4] = uint8(m.vers >> 8)
x[5] = uint8(m.vers)
copy(x[6:38], m.random)
x[38] = uint8(len(m.sessionId))
copy(x[39:39+len(m.sessionId)], m.sessionId)
z := x[39+len(m.sessionId):]
z[0] = uint8(m.cipherSuite >> 8)
z[1] = uint8(m.cipherSuite)
z[2] = uint8(m.compressionMethod)
 
z = z[3:]
if numExtensions > 0 {
z[0] = byte(extensionsLength >> 8)
z[1] = byte(extensionsLength)
z = z[2:]
}
if m.nextProtoNeg {
z[0] = byte(extensionNextProtoNeg >> 8)
z[1] = byte(extensionNextProtoNeg)
z[2] = byte(nextProtoLen >> 8)
z[3] = byte(nextProtoLen)
z = z[4:]
 
for _, v := range m.nextProtos {
l := len(v)
if l > 255 {
l = 255
}
z[0] = byte(l)
copy(z[1:], []byte(v[0:l]))
z = z[1+l:]
}
}
if m.ocspStapling {
z[0] = byte(extensionStatusRequest >> 8)
z[1] = byte(extensionStatusRequest)
z = z[4:]
}
 
m.raw = x
 
return x
}
 
func (m *serverHelloMsg) unmarshal(data []byte) bool {
if len(data) < 42 {
return false
}
m.raw = data
m.vers = uint16(data[4])<<8 | uint16(data[5])
m.random = data[6:38]
sessionIdLen := int(data[38])
if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
return false
}
m.sessionId = data[39 : 39+sessionIdLen]
data = data[39+sessionIdLen:]
if len(data) < 3 {
return false
}
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
m.compressionMethod = data[2]
data = data[3:]
 
m.nextProtoNeg = false
m.nextProtos = nil
m.ocspStapling = false
 
if len(data) == 0 {
// ServerHello is optionally followed by extension data
return true
}
if len(data) < 2 {
return false
}
 
extensionsLength := int(data[0])<<8 | int(data[1])
data = data[2:]
if len(data) != extensionsLength {
return false
}
 
for len(data) != 0 {
if len(data) < 4 {
return false
}
extension := uint16(data[0])<<8 | uint16(data[1])
length := int(data[2])<<8 | int(data[3])
data = data[4:]
if len(data) < length {
return false
}
 
switch extension {
case extensionNextProtoNeg:
m.nextProtoNeg = true
d := data
for len(d) > 0 {
l := int(d[0])
d = d[1:]
if l == 0 || l > len(d) {
return false
}
m.nextProtos = append(m.nextProtos, string(d[0:l]))
d = d[l:]
}
case extensionStatusRequest:
if length > 0 {
return false
}
m.ocspStapling = true
}
data = data[length:]
}
 
return true
}
 
type certificateMsg struct {
raw []byte
certificates [][]byte
}
 
func (m *certificateMsg) equal(i interface{}) bool {
m1, ok := i.(*certificateMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
eqByteSlices(m.certificates, m1.certificates)
}
 
func (m *certificateMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
}
 
var i int
for _, slice := range m.certificates {
i += len(slice)
}
 
length := 3 + 3*len(m.certificates) + i
x = make([]byte, 4+length)
x[0] = typeCertificate
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
 
certificateOctets := length - 3
x[4] = uint8(certificateOctets >> 16)
x[5] = uint8(certificateOctets >> 8)
x[6] = uint8(certificateOctets)
 
y := x[7:]
for _, slice := range m.certificates {
y[0] = uint8(len(slice) >> 16)
y[1] = uint8(len(slice) >> 8)
y[2] = uint8(len(slice))
copy(y[3:], slice)
y = y[3+len(slice):]
}
 
m.raw = x
return
}
 
func (m *certificateMsg) unmarshal(data []byte) bool {
if len(data) < 7 {
return false
}
 
m.raw = data
certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
if uint32(len(data)) != certsLen+7 {
return false
}
 
numCerts := 0
d := data[7:]
for certsLen > 0 {
if len(d) < 4 {
return false
}
certLen := uint32(d[0])<<24 | uint32(d[1])<<8 | uint32(d[2])
if uint32(len(d)) < 3+certLen {
return false
}
d = d[3+certLen:]
certsLen -= 3 + certLen
numCerts++
}
 
m.certificates = make([][]byte, numCerts)
d = data[7:]
for i := 0; i < numCerts; i++ {
certLen := uint32(d[0])<<24 | uint32(d[1])<<8 | uint32(d[2])
m.certificates[i] = d[3 : 3+certLen]
d = d[3+certLen:]
}
 
return true
}
 
type serverKeyExchangeMsg struct {
raw []byte
key []byte
}
 
func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
m1, ok := i.(*serverKeyExchangeMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
bytes.Equal(m.key, m1.key)
}
 
func (m *serverKeyExchangeMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
length := len(m.key)
x := make([]byte, length+4)
x[0] = typeServerKeyExchange
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
copy(x[4:], m.key)
 
m.raw = x
return x
}
 
func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
m.raw = data
if len(data) < 4 {
return false
}
m.key = data[4:]
return true
}
 
type certificateStatusMsg struct {
raw []byte
statusType uint8
response []byte
}
 
func (m *certificateStatusMsg) equal(i interface{}) bool {
m1, ok := i.(*certificateStatusMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
m.statusType == m1.statusType &&
bytes.Equal(m.response, m1.response)
}
 
func (m *certificateStatusMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
 
var x []byte
if m.statusType == statusTypeOCSP {
x = make([]byte, 4+4+len(m.response))
x[0] = typeCertificateStatus
l := len(m.response) + 4
x[1] = byte(l >> 16)
x[2] = byte(l >> 8)
x[3] = byte(l)
x[4] = statusTypeOCSP
 
l -= 4
x[5] = byte(l >> 16)
x[6] = byte(l >> 8)
x[7] = byte(l)
copy(x[8:], m.response)
} else {
x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
}
 
m.raw = x
return x
}
 
func (m *certificateStatusMsg) unmarshal(data []byte) bool {
m.raw = data
if len(data) < 5 {
return false
}
m.statusType = data[4]
 
m.response = nil
if m.statusType == statusTypeOCSP {
if len(data) < 8 {
return false
}
respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
if uint32(len(data)) != 4+4+respLen {
return false
}
m.response = data[8:]
}
return true
}
 
type serverHelloDoneMsg struct{}
 
func (m *serverHelloDoneMsg) equal(i interface{}) bool {
_, ok := i.(*serverHelloDoneMsg)
return ok
}
 
func (m *serverHelloDoneMsg) marshal() []byte {
x := make([]byte, 4)
x[0] = typeServerHelloDone
return x
}
 
func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
return len(data) == 4
}
 
type clientKeyExchangeMsg struct {
raw []byte
ciphertext []byte
}
 
func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
m1, ok := i.(*clientKeyExchangeMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
bytes.Equal(m.ciphertext, m1.ciphertext)
}
 
func (m *clientKeyExchangeMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
length := len(m.ciphertext)
x := make([]byte, length+4)
x[0] = typeClientKeyExchange
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
copy(x[4:], m.ciphertext)
 
m.raw = x
return x
}
 
func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
m.raw = data
if len(data) < 4 {
return false
}
l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
if l != len(data)-4 {
return false
}
m.ciphertext = data[4:]
return true
}
 
type finishedMsg struct {
raw []byte
verifyData []byte
}
 
func (m *finishedMsg) equal(i interface{}) bool {
m1, ok := i.(*finishedMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
bytes.Equal(m.verifyData, m1.verifyData)
}
 
func (m *finishedMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
}
 
x = make([]byte, 4+len(m.verifyData))
x[0] = typeFinished
x[3] = byte(len(m.verifyData))
copy(x[4:], m.verifyData)
m.raw = x
return
}
 
func (m *finishedMsg) unmarshal(data []byte) bool {
m.raw = data
if len(data) < 4 {
return false
}
m.verifyData = data[4:]
return true
}
 
type nextProtoMsg struct {
raw []byte
proto string
}
 
func (m *nextProtoMsg) equal(i interface{}) bool {
m1, ok := i.(*nextProtoMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
m.proto == m1.proto
}
 
func (m *nextProtoMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
l := len(m.proto)
if l > 255 {
l = 255
}
 
padding := 32 - (l+2)%32
length := l + padding + 2
x := make([]byte, length+4)
x[0] = typeNextProtocol
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
 
y := x[4:]
y[0] = byte(l)
copy(y[1:], []byte(m.proto[0:l]))
y = y[1+l:]
y[0] = byte(padding)
 
m.raw = x
 
return x
}
 
func (m *nextProtoMsg) unmarshal(data []byte) bool {
m.raw = data
 
if len(data) < 5 {
return false
}
data = data[4:]
protoLen := int(data[0])
data = data[1:]
if len(data) < protoLen {
return false
}
m.proto = string(data[0:protoLen])
data = data[protoLen:]
 
if len(data) < 1 {
return false
}
paddingLen := int(data[0])
data = data[1:]
if len(data) != paddingLen {
return false
}
 
return true
}
 
type certificateRequestMsg struct {
raw []byte
certificateTypes []byte
certificateAuthorities [][]byte
}
 
func (m *certificateRequestMsg) equal(i interface{}) bool {
m1, ok := i.(*certificateRequestMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities)
}
 
func (m *certificateRequestMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
}
 
// See http://tools.ietf.org/html/rfc4346#section-7.4.4
length := 1 + len(m.certificateTypes) + 2
casLength := 0
for _, ca := range m.certificateAuthorities {
casLength += 2 + len(ca)
}
length += casLength
 
x = make([]byte, 4+length)
x[0] = typeCertificateRequest
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
 
x[4] = uint8(len(m.certificateTypes))
 
copy(x[5:], m.certificateTypes)
y := x[5+len(m.certificateTypes):]
y[0] = uint8(casLength >> 8)
y[1] = uint8(casLength)
y = y[2:]
for _, ca := range m.certificateAuthorities {
y[0] = uint8(len(ca) >> 8)
y[1] = uint8(len(ca))
y = y[2:]
copy(y, ca)
y = y[len(ca):]
}
 
m.raw = x
return
}
 
func (m *certificateRequestMsg) unmarshal(data []byte) bool {
m.raw = data
 
if len(data) < 5 {
return false
}
 
length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
if uint32(len(data))-4 != length {
return false
}
 
numCertTypes := int(data[4])
data = data[5:]
if numCertTypes == 0 || len(data) <= numCertTypes {
return false
}
 
m.certificateTypes = make([]byte, numCertTypes)
if copy(m.certificateTypes, data) != numCertTypes {
return false
}
 
data = data[numCertTypes:]
 
if len(data) < 2 {
return false
}
casLength := uint16(data[0])<<8 | uint16(data[1])
data = data[2:]
if len(data) < int(casLength) {
return false
}
cas := make([]byte, casLength)
copy(cas, data)
data = data[casLength:]
 
m.certificateAuthorities = nil
for len(cas) > 0 {
if len(cas) < 2 {
return false
}
caLen := uint16(cas[0])<<8 | uint16(cas[1])
cas = cas[2:]
 
if len(cas) < int(caLen) {
return false
}
 
m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
cas = cas[caLen:]
}
if len(data) > 0 {
return false
}
 
return true
}
 
type certificateVerifyMsg struct {
raw []byte
signature []byte
}
 
func (m *certificateVerifyMsg) equal(i interface{}) bool {
m1, ok := i.(*certificateVerifyMsg)
if !ok {
return false
}
 
return bytes.Equal(m.raw, m1.raw) &&
bytes.Equal(m.signature, m1.signature)
}
 
func (m *certificateVerifyMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
}
 
// See http://tools.ietf.org/html/rfc4346#section-7.4.8
siglength := len(m.signature)
length := 2 + siglength
x = make([]byte, 4+length)
x[0] = typeCertificateVerify
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
x[4] = uint8(siglength >> 8)
x[5] = uint8(siglength)
copy(x[6:], m.signature)
 
m.raw = x
 
return
}
 
func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
m.raw = data
 
if len(data) < 6 {
return false
}
 
length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
if uint32(len(data))-4 != length {
return false
}
 
siglength := int(data[4])<<8 + int(data[5])
if len(data)-6 != siglength {
return false
}
 
m.signature = data[6:]
 
return true
}
 
func eqUint16s(x, y []uint16) bool {
if len(x) != len(y) {
return false
}
for i, v := range x {
if y[i] != v {
return false
}
}
return true
}
 
func eqStrings(x, y []string) bool {
if len(x) != len(y) {
return false
}
for i, v := range x {
if y[i] != v {
return false
}
}
return true
}
 
func eqByteSlices(x, y [][]byte) bool {
if len(x) != len(y) {
return false
}
for i, v := range x {
if !bytes.Equal(v, y[i]) {
return false
}
}
return true
}
/tls/key_agreement.go
0,0 → 1,249
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"crypto"
"crypto/elliptic"
"crypto/md5"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"errors"
"io"
"math/big"
)
 
// rsaKeyAgreement implements the standard TLS key agreement where the client
// encrypts the pre-master secret to the server's public key.
type rsaKeyAgreement struct{}
 
func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
return nil, nil
}
 
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
preMasterSecret := make([]byte, 48)
_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
if err != nil {
return nil, err
}
 
if len(ckx.ciphertext) < 2 {
return nil, errors.New("bad ClientKeyExchange")
}
 
ciphertext := ckx.ciphertext
if version != versionSSL30 {
ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
if ciphertextLen != len(ckx.ciphertext)-2 {
return nil, errors.New("bad ClientKeyExchange")
}
ciphertext = ckx.ciphertext[2:]
}
 
err = rsa.DecryptPKCS1v15SessionKey(config.rand(), config.Certificates[0].PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
if err != nil {
return nil, err
}
// We don't check the version number in the premaster secret. For one,
// by checking it, we would leak information about the validity of the
// encrypted pre-master secret. Secondly, it provides only a small
// benefit against a downgrade attack and some implementations send the
// wrong version anyway. See the discussion at the end of section
// 7.4.7.1 of RFC 4346.
return preMasterSecret, nil
}
 
func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
return errors.New("unexpected ServerKeyExchange")
}
 
func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
preMasterSecret := make([]byte, 48)
preMasterSecret[0] = byte(clientHello.vers >> 8)
preMasterSecret[1] = byte(clientHello.vers)
_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
if err != nil {
return nil, nil, err
}
 
encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
if err != nil {
return nil, nil, err
}
ckx := new(clientKeyExchangeMsg)
ckx.ciphertext = make([]byte, len(encrypted)+2)
ckx.ciphertext[0] = byte(len(encrypted) >> 8)
ckx.ciphertext[1] = byte(len(encrypted))
copy(ckx.ciphertext[2:], encrypted)
return preMasterSecret, ckx, nil
}
 
// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
// concatenation of an MD5 and SHA1 hash.
func md5SHA1Hash(slices ...[]byte) []byte {
md5sha1 := make([]byte, md5.Size+sha1.Size)
hmd5 := md5.New()
for _, slice := range slices {
hmd5.Write(slice)
}
copy(md5sha1, hmd5.Sum(nil))
 
hsha1 := sha1.New()
for _, slice := range slices {
hsha1.Write(slice)
}
copy(md5sha1[md5.Size:], hsha1.Sum(nil))
return md5sha1
}
 
// ecdheRSAKeyAgreement implements a TLS key agreement where the server
// generates a ephemeral EC public/private key pair and signs it. The
// pre-master secret is then calculated using ECDH.
type ecdheRSAKeyAgreement struct {
privateKey []byte
curve elliptic.Curve
x, y *big.Int
}
 
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
var curveid uint16
 
Curve:
for _, c := range clientHello.supportedCurves {
switch c {
case curveP256:
ka.curve = elliptic.P256()
curveid = c
break Curve
case curveP384:
ka.curve = elliptic.P384()
curveid = c
break Curve
case curveP521:
ka.curve = elliptic.P521()
curveid = c
break Curve
}
}
 
var x, y *big.Int
var err error
ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
if err != nil {
return nil, err
}
ecdhePublic := elliptic.Marshal(ka.curve, x, y)
 
// http://tools.ietf.org/html/rfc4492#section-5.4
serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
serverECDHParams[0] = 3 // named curve
serverECDHParams[1] = byte(curveid >> 8)
serverECDHParams[2] = byte(curveid)
serverECDHParams[3] = byte(len(ecdhePublic))
copy(serverECDHParams[4:], ecdhePublic)
 
md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams)
sig, err := rsa.SignPKCS1v15(config.rand(), config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1)
if err != nil {
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
}
 
skx := new(serverKeyExchangeMsg)
skx.key = make([]byte, len(serverECDHParams)+2+len(sig))
copy(skx.key, serverECDHParams)
k := skx.key[len(serverECDHParams):]
k[0] = byte(len(sig) >> 8)
k[1] = byte(len(sig))
copy(k[2:], sig)
 
return skx, nil
}
 
func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
return nil, errors.New("bad ClientKeyExchange")
}
x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
if x == nil {
return nil, errors.New("bad ClientKeyExchange")
}
x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
xBytes := x.Bytes()
copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
 
return preMasterSecret, nil
}
 
var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
 
func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
if len(skx.key) < 4 {
return errServerKeyExchange
}
if skx.key[0] != 3 { // named curve
return errors.New("server selected unsupported curve")
}
curveid := uint16(skx.key[1])<<8 | uint16(skx.key[2])
 
switch curveid {
case curveP256:
ka.curve = elliptic.P256()
case curveP384:
ka.curve = elliptic.P384()
case curveP521:
ka.curve = elliptic.P521()
default:
return errors.New("server selected unsupported curve")
}
 
publicLen := int(skx.key[3])
if publicLen+4 > len(skx.key) {
return errServerKeyExchange
}
ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
if ka.x == nil {
return errServerKeyExchange
}
serverECDHParams := skx.key[:4+publicLen]
 
sig := skx.key[4+publicLen:]
if len(sig) < 2 {
return errServerKeyExchange
}
sigLen := int(sig[0])<<8 | int(sig[1])
if sigLen+2 != len(sig) {
return errServerKeyExchange
}
sig = sig[2:]
 
md5sha1 := md5SHA1Hash(clientHello.random, serverHello.random, serverECDHParams)
return rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), crypto.MD5SHA1, md5sha1, sig)
}
 
func (ka *ecdheRSAKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
if ka.curve == nil {
return nil, nil, errors.New("missing ServerKeyExchange message")
}
priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
if err != nil {
return nil, nil, err
}
x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
xBytes := x.Bytes()
copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
 
serialized := elliptic.Marshal(ka.curve, mx, my)
 
ckx := new(clientKeyExchangeMsg)
ckx.ciphertext = make([]byte, 1+len(serialized))
ckx.ciphertext[0] = byte(len(serialized))
copy(ckx.ciphertext[1:], serialized)
 
return preMasterSecret, ckx, nil
}
/tls/root_stub.go
0,0 → 1,10
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// +build plan9 darwin,!cgo
 
package tls
 
func initDefaultRoots() {
}
/tls/root_test.go
0,0 → 1,36
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"testing"
)
 
var tlsServers = []string{
"google.com:443",
"github.com:443",
"twitter.com:443",
}
 
func TestOSCertBundles(t *testing.T) {
defaultRoots()
 
if testing.Short() {
t.Logf("skipping certificate tests in short mode")
return
}
 
for _, addr := range tlsServers {
conn, err := Dial("tcp", addr, nil)
if err != nil {
t.Errorf("unable to verify %v: %v", addr, err)
continue
}
err = conn.Close()
if err != nil {
t.Error(err)
}
}
}
/tls/handshake_client_test.go
0,0 → 1,212
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"bytes"
"flag"
"io"
"net"
"testing"
)
 
func testClientScript(t *testing.T, name string, clientScript [][]byte, config *Config) {
c, s := net.Pipe()
cli := Client(c, config)
go func() {
cli.Write([]byte("hello\n"))
cli.Close()
c.Close()
}()
 
defer c.Close()
for i, b := range clientScript {
if i%2 == 1 {
s.Write(b)
continue
}
bb := make([]byte, len(b))
_, err := io.ReadFull(s, bb)
if err != nil {
t.Fatalf("%s #%d: %s", name, i, err)
}
if !bytes.Equal(b, bb) {
t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b)
}
}
}
 
func TestHandshakeClientRC4(t *testing.T) {
testClientScript(t, "RC4", rc4ClientScript, testConfig)
}
 
var connect = flag.Bool("connect", false, "connect to a TLS server on :10443")
 
func TestRunClient(t *testing.T) {
if !*connect {
return
}
 
testConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
 
conn, err := Dial("tcp", "127.0.0.1:10443", testConfig)
if err != nil {
t.Fatal(err)
}
 
conn.Write([]byte("hello\n"))
conn.Close()
}
 
// Script of interaction with gnutls implementation.
// The values for this test are obtained by building and running in client mode:
// % gotest -test.run "TestRunClient" -connect
// and then:
// % gnutls-serv -p 10443 --debug 100 --x509keyfile key.pem --x509certfile cert.pem -a > /tmp/log 2>&1
// % python parse-gnutls-cli-debug-log.py < /tmp/log
//
// Where key.pem is:
// -----BEGIN RSA PRIVATE KEY-----
// MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
// TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
// OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
// gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
// rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
// PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
// vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
// -----END RSA PRIVATE KEY-----
//
// and cert.pem is:
// -----BEGIN CERTIFICATE-----
// MIIBoDCCAUoCAQAwDQYJKoZIhvcNAQEEBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV
// BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD
// VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw05NzA5MDkwMzQxMjZa
// Fw05NzEwMDkwMzQxMjZaMF4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
// YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMT
// DkVyaWMgdGhlIFlvdW5nMFEwCQYFKw4DAgwFAANEAAJBALVEqPODnpI4rShlY8S7
// tB713JNvabvn6Gned7zylwLLiXQAo/PAT6mfdWPTyCX9RlId/Aroh1ou893BA32Q
// sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJoX+CpCvFy+JVh9HpSjCpSNKO
// 19raHv98hKAUJuP9HyM+SUsffO6mAIgitUaqW8/wDMePhEC3
// -----END CERTIFICATE-----
var rc4ClientScript = [][]byte{
{
0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00,
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05,
0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00,
0x46, 0x03, 0x01, 0x4d, 0x0a, 0x56, 0x16, 0xb5,
0x91, 0xd1, 0xcb, 0x80, 0x4d, 0xc7, 0x46, 0xf3,
0x37, 0x0c, 0xef, 0xea, 0x64, 0x11, 0x14, 0x56,
0x97, 0x9b, 0xc5, 0x67, 0x08, 0xb7, 0x13, 0xea,
0xf8, 0xc9, 0xb3, 0x20, 0xe2, 0xfc, 0x41, 0xf6,
0x96, 0x90, 0x9d, 0x43, 0x9b, 0xe9, 0x6e, 0xf8,
0x41, 0x16, 0xcc, 0xf3, 0xc7, 0xde, 0xda, 0x5a,
0xa1, 0x33, 0x69, 0xe2, 0xde, 0x5b, 0xaf, 0x2a,
0x92, 0xe7, 0xd4, 0xa0, 0x00, 0x05, 0x00, 0x16,
0x03, 0x01, 0x01, 0xf7, 0x0b, 0x00, 0x01, 0xf3,
0x00, 0x01, 0xf0, 0x00, 0x01, 0xed, 0x30, 0x82,
0x01, 0xe9, 0x30, 0x82, 0x01, 0x52, 0x02, 0x01,
0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00,
0x30, 0x5b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31,
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
0x13, 0x0a, 0x51, 0x75, 0x65, 0x65, 0x6e, 0x73,
0x6c, 0x61, 0x6e, 0x64, 0x31, 0x1a, 0x30, 0x18,
0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43,
0x72, 0x79, 0x70, 0x74, 0x53, 0x6f, 0x66, 0x74,
0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x12, 0x54, 0x65, 0x73, 0x74, 0x20,
0x43, 0x41, 0x20, 0x28, 0x31, 0x30, 0x32, 0x34,
0x20, 0x62, 0x69, 0x74, 0x29, 0x30, 0x1e, 0x17,
0x0d, 0x30, 0x30, 0x31, 0x30, 0x31, 0x36, 0x32,
0x32, 0x33, 0x31, 0x30, 0x33, 0x5a, 0x17, 0x0d,
0x30, 0x33, 0x30, 0x31, 0x31, 0x34, 0x32, 0x32,
0x33, 0x31, 0x30, 0x33, 0x5a, 0x30, 0x63, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x51,
0x75, 0x65, 0x65, 0x6e, 0x73, 0x6c, 0x61, 0x6e,
0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x11, 0x43, 0x72, 0x79, 0x70,
0x74, 0x53, 0x6f, 0x66, 0x74, 0x20, 0x50, 0x74,
0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x23, 0x30,
0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74,
0x65, 0x73, 0x74, 0x20, 0x63, 0x65, 0x72, 0x74,
0x20, 0x28, 0x35, 0x31, 0x32, 0x20, 0x62, 0x69,
0x74, 0x29, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48,
0x02, 0x41, 0x00, 0x9f, 0xb3, 0xc3, 0x84, 0x27,
0x95, 0xff, 0x12, 0x31, 0x52, 0x0f, 0x15, 0xef,
0x46, 0x11, 0xc4, 0xad, 0x80, 0xe6, 0x36, 0x5b,
0x0f, 0xdd, 0x80, 0xd7, 0x61, 0x8d, 0xe0, 0xfc,
0x72, 0x45, 0x09, 0x34, 0xfe, 0x55, 0x66, 0x45,
0x43, 0x4c, 0x68, 0x97, 0x6a, 0xfe, 0xa8, 0xa0,
0xa5, 0xdf, 0x5f, 0x78, 0xff, 0xee, 0xd7, 0x64,
0xb8, 0x3f, 0x04, 0xcb, 0x6f, 0xff, 0x2a, 0xfe,
0xfe, 0xb9, 0xed, 0x02, 0x03, 0x01, 0x00, 0x01,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03,
0x81, 0x81, 0x00, 0x93, 0xd2, 0x0a, 0xc5, 0x41,
0xe6, 0x5a, 0xa9, 0x86, 0xf9, 0x11, 0x87, 0xe4,
0xdb, 0x45, 0xe2, 0xc5, 0x95, 0x78, 0x1a, 0x6c,
0x80, 0x6d, 0x73, 0x1f, 0xb4, 0x6d, 0x44, 0xa3,
0xba, 0x86, 0x88, 0xc8, 0x58, 0xcd, 0x1c, 0x06,
0x35, 0x6c, 0x44, 0x62, 0x88, 0xdf, 0xe4, 0xf6,
0x64, 0x61, 0x95, 0xef, 0x4a, 0xa6, 0x7f, 0x65,
0x71, 0xd7, 0x6b, 0x88, 0x39, 0xf6, 0x32, 0xbf,
0xac, 0x93, 0x67, 0x69, 0x51, 0x8c, 0x93, 0xec,
0x48, 0x5f, 0xc9, 0xb1, 0x42, 0xf9, 0x55, 0xd2,
0x7e, 0x4e, 0xf4, 0xf2, 0x21, 0x6b, 0x90, 0x57,
0xe6, 0xd7, 0x99, 0x9e, 0x41, 0xca, 0x80, 0xbf,
0x1a, 0x28, 0xa2, 0xca, 0x5b, 0x50, 0x4a, 0xed,
0x84, 0xe7, 0x82, 0xc7, 0xd2, 0xcf, 0x36, 0x9e,
0x6a, 0x67, 0xb9, 0x88, 0xa7, 0xf3, 0x8a, 0xd0,
0x04, 0xf8, 0xe8, 0xc6, 0x17, 0xe3, 0xc5, 0x29,
0xbc, 0x17, 0xf1, 0x16, 0x03, 0x01, 0x00, 0x04,
0x0e, 0x00, 0x00, 0x00,
},
 
{
0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00,
0x42, 0x00, 0x40, 0x87, 0xa1, 0x1f, 0x14, 0xe1,
0xfb, 0x91, 0xac, 0x58, 0x2e, 0xf3, 0x71, 0xce,
0x01, 0x85, 0x2c, 0xc7, 0xfe, 0x84, 0x87, 0x82,
0xb7, 0x57, 0xdb, 0x37, 0x4d, 0x46, 0x83, 0x67,
0x52, 0x82, 0x51, 0x01, 0x95, 0x23, 0x68, 0x69,
0x6b, 0xd0, 0xa7, 0xa7, 0xe5, 0x88, 0xd0, 0x47,
0x71, 0xb8, 0xd2, 0x03, 0x05, 0x25, 0x56, 0x5c,
0x10, 0x08, 0xc6, 0x9b, 0xd4, 0x67, 0xcd, 0x28,
0xbe, 0x9c, 0x48, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xc1, 0xb8,
0xd3, 0x7f, 0xc5, 0xc2, 0x5a, 0x1d, 0x6d, 0x5b,
0x2d, 0x5c, 0x82, 0x87, 0xc2, 0x6f, 0x0d, 0x63,
0x7b, 0x72, 0x2b, 0xda, 0x69, 0xc4, 0xfe, 0x3c,
0x84, 0xa1, 0x5a, 0x62, 0x38, 0x37, 0xc6, 0x54,
0x25, 0x2a,
},
 
{
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
0x01, 0x00, 0x24, 0xea, 0x88, 0x9c, 0x00, 0xf6,
0x35, 0xb8, 0x42, 0x7f, 0x15, 0x17, 0x76, 0x5e,
0x4b, 0x24, 0xcb, 0x7e, 0xa0, 0x7b, 0xc3, 0x70,
0x52, 0x0a, 0x88, 0x2a, 0x7a, 0x45, 0x59, 0x90,
0x59, 0xac, 0xc6, 0xb5, 0x56, 0x55, 0x96,
},
}
/tls/handshake_client.go
0,0 → 1,339
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"bytes"
"crypto"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
"errors"
"io"
"strconv"
)
 
func (c *Conn) clientHandshake() error {
finishedHash := newFinishedHash(versionTLS10)
 
if c.config == nil {
c.config = defaultConfig()
}
 
hello := &clientHelloMsg{
vers: maxVersion,
cipherSuites: c.config.cipherSuites(),
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
ocspStapling: true,
serverName: c.config.ServerName,
supportedCurves: []uint16{curveP256, curveP384, curveP521},
supportedPoints: []uint8{pointFormatUncompressed},
nextProtoNeg: len(c.config.NextProtos) > 0,
}
 
t := uint32(c.config.time().Unix())
hello.random[0] = byte(t >> 24)
hello.random[1] = byte(t >> 16)
hello.random[2] = byte(t >> 8)
hello.random[3] = byte(t)
_, err := io.ReadFull(c.config.rand(), hello.random[4:])
if err != nil {
c.sendAlert(alertInternalError)
return errors.New("short read from Rand")
}
 
finishedHash.Write(hello.marshal())
c.writeRecord(recordTypeHandshake, hello.marshal())
 
msg, err := c.readHandshake()
if err != nil {
return err
}
serverHello, ok := msg.(*serverHelloMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
finishedHash.Write(serverHello.marshal())
 
vers, ok := mutualVersion(serverHello.vers)
if !ok || vers < versionTLS10 {
// TLS 1.0 is the minimum version supported as a client.
return c.sendAlert(alertProtocolVersion)
}
c.vers = vers
c.haveVers = true
 
if serverHello.compressionMethod != compressionNone {
return c.sendAlert(alertUnexpectedMessage)
}
 
if !hello.nextProtoNeg && serverHello.nextProtoNeg {
c.sendAlert(alertHandshakeFailure)
return errors.New("server advertised unrequested NPN")
}
 
suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
if suite == nil {
return c.sendAlert(alertHandshakeFailure)
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
certMsg, ok := msg.(*certificateMsg)
if !ok || len(certMsg.certificates) == 0 {
return c.sendAlert(alertUnexpectedMessage)
}
finishedHash.Write(certMsg.marshal())
 
certs := make([]*x509.Certificate, len(certMsg.certificates))
for i, asn1Data := range certMsg.certificates {
cert, err := x509.ParseCertificate(asn1Data)
if err != nil {
c.sendAlert(alertBadCertificate)
return errors.New("failed to parse certificate from server: " + err.Error())
}
certs[i] = cert
}
 
if !c.config.InsecureSkipVerify {
opts := x509.VerifyOptions{
Roots: c.config.rootCAs(),
CurrentTime: c.config.time(),
DNSName: c.config.ServerName,
Intermediates: x509.NewCertPool(),
}
 
for i, cert := range certs {
if i == 0 {
continue
}
opts.Intermediates.AddCert(cert)
}
c.verifiedChains, err = certs[0].Verify(opts)
if err != nil {
c.sendAlert(alertBadCertificate)
return err
}
}
 
if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok {
return c.sendAlert(alertUnsupportedCertificate)
}
 
c.peerCertificates = certs
 
if serverHello.ocspStapling {
msg, err = c.readHandshake()
if err != nil {
return err
}
cs, ok := msg.(*certificateStatusMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
finishedHash.Write(cs.marshal())
 
if cs.statusType == statusTypeOCSP {
c.ocspResponse = cs.response
}
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
 
keyAgreement := suite.ka()
 
skx, ok := msg.(*serverKeyExchangeMsg)
if ok {
finishedHash.Write(skx.marshal())
err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx)
if err != nil {
c.sendAlert(alertUnexpectedMessage)
return err
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
}
 
var certToSend *Certificate
certReq, ok := msg.(*certificateRequestMsg)
if ok {
// RFC 4346 on the certificateAuthorities field:
// A list of the distinguished names of acceptable certificate
// authorities. These distinguished names may specify a desired
// distinguished name for a root CA or for a subordinate CA;
// thus, this message can be used to describe both known roots
// and a desired authorization space. If the
// certificate_authorities list is empty then the client MAY
// send any certificate of the appropriate
// ClientCertificateType, unless there is some external
// arrangement to the contrary.
 
finishedHash.Write(certReq.marshal())
 
// For now, we only know how to sign challenges with RSA
rsaAvail := false
for _, certType := range certReq.certificateTypes {
if certType == certTypeRSASign {
rsaAvail = true
break
}
}
 
// We need to search our list of client certs for one
// where SignatureAlgorithm is RSA and the Issuer is in
// certReq.certificateAuthorities
findCert:
for i, cert := range c.config.Certificates {
if !rsaAvail {
continue
}
 
leaf := cert.Leaf
if leaf == nil {
if leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil {
c.sendAlert(alertInternalError)
return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
}
}
 
if leaf.PublicKeyAlgorithm != x509.RSA {
continue
}
 
if len(certReq.certificateAuthorities) == 0 {
// they gave us an empty list, so just take the
// first RSA cert from c.config.Certificates
certToSend = &cert
break
}
 
for _, ca := range certReq.certificateAuthorities {
if bytes.Equal(leaf.RawIssuer, ca) {
certToSend = &cert
break findCert
}
}
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
}
 
shd, ok := msg.(*serverHelloDoneMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
finishedHash.Write(shd.marshal())
 
if certToSend != nil {
certMsg = new(certificateMsg)
certMsg.certificates = certToSend.Certificate
finishedHash.Write(certMsg.marshal())
c.writeRecord(recordTypeHandshake, certMsg.marshal())
}
 
preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0])
if err != nil {
c.sendAlert(alertInternalError)
return err
}
if ckx != nil {
finishedHash.Write(ckx.marshal())
c.writeRecord(recordTypeHandshake, ckx.marshal())
}
 
if certToSend != nil {
certVerify := new(certificateVerifyMsg)
digest := make([]byte, 0, 36)
digest = finishedHash.serverMD5.Sum(digest)
digest = finishedHash.serverSHA1.Sum(digest)
signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, digest)
if err != nil {
return c.sendAlert(alertInternalError)
}
certVerify.signature = signed
 
finishedHash.Write(certVerify.marshal())
c.writeRecord(recordTypeHandshake, certVerify.marshal())
}
 
masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
keysFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
 
clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */ )
clientHash := suite.mac(c.vers, clientMAC)
c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
 
if serverHello.nextProtoNeg {
nextProto := new(nextProtoMsg)
proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos)
nextProto.proto = proto
c.clientProtocol = proto
c.clientProtocolFallback = fallback
 
finishedHash.Write(nextProto.marshal())
c.writeRecord(recordTypeHandshake, nextProto.marshal())
}
 
finished := new(finishedMsg)
finished.verifyData = finishedHash.clientSum(masterSecret)
finishedHash.Write(finished.marshal())
c.writeRecord(recordTypeHandshake, finished.marshal())
 
serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */ )
serverHash := suite.mac(c.vers, serverMAC)
c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
c.readRecord(recordTypeChangeCipherSpec)
if c.err != nil {
return c.err
}
 
msg, err = c.readHandshake()
if err != nil {
return err
}
serverFinished, ok := msg.(*finishedMsg)
if !ok {
return c.sendAlert(alertUnexpectedMessage)
}
 
verify := finishedHash.serverSum(masterSecret)
if len(verify) != len(serverFinished.verifyData) ||
subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
return c.sendAlert(alertHandshakeFailure)
}
 
c.handshakeComplete = true
c.cipherSuite = suite.id
return nil
}
 
// mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
// set of client and server supported protocols. The set of client supported
// protocols must not be empty. It returns the resulting protocol and flag
// indicating if the fallback case was reached.
func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
for _, s := range serverProtos {
for _, c := range clientProtos {
if s == c {
return s, false
}
}
}
 
return clientProtos[0], true
}
/tls/prf_test.go
0,0 → 1,121
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"encoding/hex"
"testing"
)
 
type testSplitPreMasterSecretTest struct {
in, out1, out2 string
}
 
var testSplitPreMasterSecretTests = []testSplitPreMasterSecretTest{
{"", "", ""},
{"00", "00", "00"},
{"0011", "00", "11"},
{"001122", "0011", "1122"},
{"00112233", "0011", "2233"},
}
 
func TestSplitPreMasterSecret(t *testing.T) {
for i, test := range testSplitPreMasterSecretTests {
in, _ := hex.DecodeString(test.in)
out1, out2 := splitPreMasterSecret(in)
s1 := hex.EncodeToString(out1)
s2 := hex.EncodeToString(out2)
if s1 != test.out1 || s2 != test.out2 {
t.Errorf("#%d: got: (%s, %s) want: (%s, %s)", i, s1, s2, test.out1, test.out2)
}
}
}
 
type testKeysFromTest struct {
version uint16
preMasterSecret string
clientRandom, serverRandom string
masterSecret string
clientMAC, serverMAC string
clientKey, serverKey string
macLen, keyLen int
}
 
func TestKeysFromPreMasterSecret(t *testing.T) {
for i, test := range testKeysFromTests {
in, _ := hex.DecodeString(test.preMasterSecret)
clientRandom, _ := hex.DecodeString(test.clientRandom)
serverRandom, _ := hex.DecodeString(test.serverRandom)
master, clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromPreMasterSecret(test.version, in, clientRandom, serverRandom, test.macLen, test.keyLen, 0)
masterString := hex.EncodeToString(master)
clientMACString := hex.EncodeToString(clientMAC)
serverMACString := hex.EncodeToString(serverMAC)
clientKeyString := hex.EncodeToString(clientKey)
serverKeyString := hex.EncodeToString(serverKey)
if masterString != test.masterSecret ||
clientMACString != test.clientMAC ||
serverMACString != test.serverMAC ||
clientKeyString != test.clientKey ||
serverKeyString != test.serverKey {
t.Errorf("#%d: got: (%s, %s, %s, %s, %s) want: (%s, %s, %s, %s, %s)", i, masterString, clientMACString, serverMACString, clientKeyString, serverKeyString, test.masterSecret, test.clientMAC, test.serverMAC, test.clientKey, test.serverKey)
}
}
}
 
// These test vectors were generated from GnuTLS using `gnutls-cli --insecure -d 9 `
var testKeysFromTests = []testKeysFromTest{
{
versionTLS10,
"0302cac83ad4b1db3b9ab49ad05957de2a504a634a386fc600889321e1a971f57479466830ac3e6f468e87f5385fa0c5",
"4ae66303755184a3917fcb44880605fcc53baa01912b22ed94473fc69cebd558",
"4ae663020ec16e6bb5130be918cfcafd4d765979a3136a5d50c593446e4e44db",
"3d851bab6e5556e959a16bc36d66cfae32f672bfa9ecdef6096cbb1b23472df1da63dbbd9827606413221d149ed08ceb",
"805aaa19b3d2c0a0759a4b6c9959890e08480119",
"2d22f9fe519c075c16448305ceee209fc24ad109",
"d50b5771244f850cd8117a9ccafe2cf1",
"e076e33206b30507a85c32855acd0919",
20,
16,
},
{
versionTLS10,
"03023f7527316bc12cbcd69e4b9e8275d62c028f27e65c745cfcddc7ce01bd3570a111378b63848127f1c36e5f9e4890",
"4ae66364b5ea56b20ce4e25555aed2d7e67f42788dd03f3fee4adae0459ab106",
"4ae66363ab815cbf6a248b87d6b556184e945e9b97fbdf247858b0bdafacfa1c",
"7d64be7c80c59b740200b4b9c26d0baaa1c5ae56705acbcf2307fe62beb4728c19392c83f20483801cce022c77645460",
"97742ed60a0554ca13f04f97ee193177b971e3b0",
"37068751700400e03a8477a5c7eec0813ab9e0dc",
"207cddbc600d2a200abac6502053ee5c",
"df3f94f6e1eacc753b815fe16055cd43",
20,
16,
},
{
versionTLS10,
"832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1",
"4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e",
"4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e",
"1aff2e7a2c4279d0126f57a65a77a8d9d0087cf2733366699bec27eb53d5740705a8574bb1acc2abbe90e44f0dd28d6c",
"3c7647c93c1379a31a609542aa44e7f117a70085",
"0d73102994be74a575a3ead8532590ca32a526d4",
"ac7581b0b6c10d85bbd905ffbf36c65e",
"ff07edde49682b45466bd2e39464b306",
20,
16,
},
{
versionSSL30,
"832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1",
"4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e",
"4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e",
"a614863e56299dcffeea2938f22c2ba023768dbe4b3f6877bc9c346c6ae529b51d9cb87ff9695ea4d01f2205584405b2",
"2c450d5b6f6e2013ac6bea6a0b32200d4e1ffb94",
"7a7a7438769536f2fb1ae49a61f0703b79b2dc53",
"f8f6b26c10f12855c9aafb1e0e839ccf",
"2b9d4b4a60cb7f396780ebff50650419",
20,
16,
},
}
/tls/root_unix.go
0,0 → 1,33
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// +build freebsd linux openbsd netbsd
 
package tls
 
import (
"crypto/x509"
"io/ioutil"
)
 
// Possible certificate files; stop after finding one.
var certFiles = []string{
"/etc/ssl/certs/ca-certificates.crt", // Linux etc
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/ssl/cert.pem", // OpenBSD
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD
}
 
func initDefaultRoots() {
roots := x509.NewCertPool()
for _, file := range certFiles {
data, err := ioutil.ReadFile(file)
if err == nil {
roots.AppendCertsFromPEM(data)
break
}
}
varDefaultRoots = roots
}
/tls/root_darwin.go
0,0 → 1,95
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
/*
// Note: We disable -Werror here because the code in this file uses a deprecated API to stay
// compatible with both Mac OS X 10.6 and 10.7. Using a deprecated function on Darwin generates
// a warning.
#cgo CFLAGS: -Wno-error -Wno-deprecated-declarations
#cgo LDFLAGS: -framework CoreFoundation -framework Security
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
 
// FetchPEMRoots fetches the system's list of trusted X.509 root certificates.
//
// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
// certificates of the system. On failure, the function returns -1.
//
// Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
// we've consumed its content.
int FetchPEMRoots(CFDataRef *pemRoots) {
if (pemRoots == NULL) {
return -1;
}
 
CFArrayRef certs = NULL;
OSStatus err = SecTrustCopyAnchorCertificates(&certs);
if (err != noErr) {
return -1;
}
 
CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
int i, ncerts = CFArrayGetCount(certs);
for (i = 0; i < ncerts; i++) {
CFDataRef data = NULL;
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
if (cert == NULL) {
continue;
}
 
// SecKeychainImportExport is deprecated in >= OS X 10.7, and has been replaced by
// SecItemExport. If we're built on a host with a Lion SDK, this code gets conditionally
// included in the output, also for binaries meant for 10.6.
//
// To make sure that we run on both Mac OS X 10.6 and 10.7 we use weak linking
// and check whether SecItemExport is available before we attempt to call it. On
// 10.6, this won't be the case, and we'll fall back to calling SecKeychainItemExport.
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (SecItemExport) {
err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
if (err != noErr) {
continue;
}
} else
#endif
if (data == NULL) {
err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
if (err != noErr) {
continue;
}
}
 
if (data != NULL) {
CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
CFRelease(data);
}
}
 
CFRelease(certs);
 
*pemRoots = combinedData;
return 0;
}
*/
import "C"
import (
"crypto/x509"
"unsafe"
)
 
func initDefaultRoots() {
roots := x509.NewCertPool()
 
var data C.CFDataRef = nil
err := C.FetchPEMRoots(&data)
if err != -1 {
defer C.CFRelease(C.CFTypeRef(data))
buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
roots.AppendCertsFromPEM(buf)
}
 
varDefaultRoots = roots
}
/tls/prf.go
0,0 → 1,235
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"hash"
)
 
// Split a premaster secret in two as specified in RFC 4346, section 5.
func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
s1 = secret[0 : (len(secret)+1)/2]
s2 = secret[len(secret)/2:]
return
}
 
// pHash implements the P_hash function, as defined in RFC 4346, section 5.
func pHash(result, secret, seed []byte, hash func() hash.Hash) {
h := hmac.New(hash, secret)
h.Write(seed)
a := h.Sum(nil)
 
j := 0
for j < len(result) {
h.Reset()
h.Write(a)
h.Write(seed)
b := h.Sum(nil)
todo := len(b)
if j+todo > len(result) {
todo = len(result) - j
}
copy(result[j:j+todo], b)
j += todo
 
h.Reset()
h.Write(a)
a = h.Sum(nil)
}
}
 
// pRF10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5.
func pRF10(result, secret, label, seed []byte) {
hashSHA1 := sha1.New
hashMD5 := md5.New
 
labelAndSeed := make([]byte, len(label)+len(seed))
copy(labelAndSeed, label)
copy(labelAndSeed[len(label):], seed)
 
s1, s2 := splitPreMasterSecret(secret)
pHash(result, s1, labelAndSeed, hashMD5)
result2 := make([]byte, len(result))
pHash(result2, s2, labelAndSeed, hashSHA1)
 
for i, b := range result2 {
result[i] ^= b
}
}
 
// pRF30 implements the SSL 3.0 pseudo-random function, as defined in
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6.
func pRF30(result, secret, label, seed []byte) {
hashSHA1 := sha1.New()
hashMD5 := md5.New()
 
done := 0
i := 0
// RFC5246 section 6.3 says that the largest PRF output needed is 128
// bytes. Since no more ciphersuites will be added to SSLv3, this will
// remain true. Each iteration gives us 16 bytes so 10 iterations will
// be sufficient.
var b [11]byte
for done < len(result) {
for j := 0; j <= i; j++ {
b[j] = 'A' + byte(i)
}
 
hashSHA1.Reset()
hashSHA1.Write(b[:i+1])
hashSHA1.Write(secret)
hashSHA1.Write(seed)
digest := hashSHA1.Sum(nil)
 
hashMD5.Reset()
hashMD5.Write(secret)
hashMD5.Write(digest)
 
done += copy(result[done:], hashMD5.Sum(nil))
i++
}
}
 
const (
tlsRandomLength = 32 // Length of a random nonce in TLS 1.1.
masterSecretLength = 48 // Length of a master secret in TLS 1.1.
finishedVerifyLength = 12 // Length of verify_data in a Finished message.
)
 
var masterSecretLabel = []byte("master secret")
var keyExpansionLabel = []byte("key expansion")
var clientFinishedLabel = []byte("client finished")
var serverFinishedLabel = []byte("server finished")
 
// keysFromPreMasterSecret generates the connection keys from the pre master
// secret, given the lengths of the MAC key, cipher key and IV, as defined in
// RFC 2246, section 6.3.
func keysFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
prf := pRF10
if version == versionSSL30 {
prf = pRF30
}
 
var seed [tlsRandomLength * 2]byte
copy(seed[0:len(clientRandom)], clientRandom)
copy(seed[len(clientRandom):], serverRandom)
masterSecret = make([]byte, masterSecretLength)
prf(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
 
copy(seed[0:len(clientRandom)], serverRandom)
copy(seed[len(serverRandom):], clientRandom)
 
n := 2*macLen + 2*keyLen + 2*ivLen
keyMaterial := make([]byte, n)
prf(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
clientMAC = keyMaterial[:macLen]
keyMaterial = keyMaterial[macLen:]
serverMAC = keyMaterial[:macLen]
keyMaterial = keyMaterial[macLen:]
clientKey = keyMaterial[:keyLen]
keyMaterial = keyMaterial[keyLen:]
serverKey = keyMaterial[:keyLen]
keyMaterial = keyMaterial[keyLen:]
clientIV = keyMaterial[:ivLen]
keyMaterial = keyMaterial[ivLen:]
serverIV = keyMaterial[:ivLen]
return
}
 
func newFinishedHash(version uint16) finishedHash {
return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New(), version}
}
 
// A finishedHash calculates the hash of a set of handshake messages suitable
// for including in a Finished message.
type finishedHash struct {
clientMD5 hash.Hash
clientSHA1 hash.Hash
serverMD5 hash.Hash
serverSHA1 hash.Hash
version uint16
}
 
func (h finishedHash) Write(msg []byte) (n int, err error) {
h.clientMD5.Write(msg)
h.clientSHA1.Write(msg)
h.serverMD5.Write(msg)
h.serverSHA1.Write(msg)
return len(msg), nil
}
 
// finishedSum10 calculates the contents of the verify_data member of a TLSv1
// Finished message given the MD5 and SHA1 hashes of a set of handshake
// messages.
func finishedSum10(md5, sha1, label, masterSecret []byte) []byte {
seed := make([]byte, len(md5)+len(sha1))
copy(seed, md5)
copy(seed[len(md5):], sha1)
out := make([]byte, finishedVerifyLength)
pRF10(out, masterSecret, label, seed)
return out
}
 
// finishedSum30 calculates the contents of the verify_data member of a SSLv3
// Finished message given the MD5 and SHA1 hashes of a set of handshake
// messages.
func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte {
md5.Write(magic[:])
md5.Write(masterSecret)
md5.Write(ssl30Pad1[:])
md5Digest := md5.Sum(nil)
 
md5.Reset()
md5.Write(masterSecret)
md5.Write(ssl30Pad2[:])
md5.Write(md5Digest)
md5Digest = md5.Sum(nil)
 
sha1.Write(magic[:])
sha1.Write(masterSecret)
sha1.Write(ssl30Pad1[:40])
sha1Digest := sha1.Sum(nil)
 
sha1.Reset()
sha1.Write(masterSecret)
sha1.Write(ssl30Pad2[:40])
sha1.Write(sha1Digest)
sha1Digest = sha1.Sum(nil)
 
ret := make([]byte, len(md5Digest)+len(sha1Digest))
copy(ret, md5Digest)
copy(ret[len(md5Digest):], sha1Digest)
return ret
}
 
var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54}
var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52}
 
// clientSum returns the contents of the verify_data member of a client's
// Finished message.
func (h finishedHash) clientSum(masterSecret []byte) []byte {
if h.version == versionSSL30 {
return finishedSum30(h.clientMD5, h.clientSHA1, masterSecret, ssl3ClientFinishedMagic)
}
 
md5 := h.clientMD5.Sum(nil)
sha1 := h.clientSHA1.Sum(nil)
return finishedSum10(md5, sha1, clientFinishedLabel, masterSecret)
}
 
// serverSum returns the contents of the verify_data member of a server's
// Finished message.
func (h finishedHash) serverSum(masterSecret []byte) []byte {
if h.version == versionSSL30 {
return finishedSum30(h.serverMD5, h.serverSHA1, masterSecret, ssl3ServerFinishedMagic)
}
 
md5 := h.serverMD5.Sum(nil)
sha1 := h.serverSHA1.Sum(nil)
return finishedSum10(md5, sha1, serverFinishedLabel, masterSecret)
}
/tls/common.go
0,0 → 1,341
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"crypto"
"crypto/rand"
"crypto/x509"
"io"
"strings"
"sync"
"time"
)
 
const (
maxPlaintext = 16384 // maximum plaintext payload length
maxCiphertext = 16384 + 2048 // maximum ciphertext payload length
recordHeaderLen = 5 // record header length
maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
 
versionSSL30 = 0x0300
versionTLS10 = 0x0301
 
minVersion = versionSSL30
maxVersion = versionTLS10
)
 
// TLS record types.
type recordType uint8
 
const (
recordTypeChangeCipherSpec recordType = 20
recordTypeAlert recordType = 21
recordTypeHandshake recordType = 22
recordTypeApplicationData recordType = 23
)
 
// TLS handshake message types.
const (
typeClientHello uint8 = 1
typeServerHello uint8 = 2
typeCertificate uint8 = 11
typeServerKeyExchange uint8 = 12
typeCertificateRequest uint8 = 13
typeServerHelloDone uint8 = 14
typeCertificateVerify uint8 = 15
typeClientKeyExchange uint8 = 16
typeFinished uint8 = 20
typeCertificateStatus uint8 = 22
typeNextProtocol uint8 = 67 // Not IANA assigned
)
 
// TLS compression types.
const (
compressionNone uint8 = 0
)
 
// TLS extension numbers
var (
extensionServerName uint16 = 0
extensionStatusRequest uint16 = 5
extensionSupportedCurves uint16 = 10
extensionSupportedPoints uint16 = 11
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
)
 
// TLS Elliptic Curves
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
var (
curveP256 uint16 = 23
curveP384 uint16 = 24
curveP521 uint16 = 25
)
 
// TLS Elliptic Curve Point Formats
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
var (
pointFormatUncompressed uint8 = 0
)
 
// TLS CertificateStatusType (RFC 3546)
const (
statusTypeOCSP uint8 = 1
)
 
// Certificate types (for certificateRequestMsg)
const (
certTypeRSASign = 1 // A certificate containing an RSA key
certTypeDSSSign = 2 // A certificate containing a DSA key
certTypeRSAFixedDH = 3 // A certificate containing a static DH key
certTypeDSSFixedDH = 4 // A certificate containing a static DH key
// Rest of these are reserved by the TLS spec
)
 
// ConnectionState records basic TLS details about the connection.
type ConnectionState struct {
HandshakeComplete bool
CipherSuite uint16
NegotiatedProtocol string
NegotiatedProtocolIsMutual bool
 
// ServerName contains the server name indicated by the client, if any.
// (Only valid for server connections.)
ServerName string
 
// the certificate chain that was presented by the other side
PeerCertificates []*x509.Certificate
// the verified certificate chains built from PeerCertificates.
VerifiedChains [][]*x509.Certificate
}
 
// ClientAuthType declares the policy the server will follow for
// TLS Client Authentication.
type ClientAuthType int
 
const (
NoClientCert ClientAuthType = iota
RequestClientCert
RequireAnyClientCert
VerifyClientCertIfGiven
RequireAndVerifyClientCert
)
 
// A Config structure is used to configure a TLS client or server. After one
// has been passed to a TLS function it must not be modified.
type Config struct {
// Rand provides the source of entropy for nonces and RSA blinding.
// If Rand is nil, TLS uses the cryptographic random reader in package
// crypto/rand.
Rand io.Reader
 
// Time returns the current time as the number of seconds since the epoch.
// If Time is nil, TLS uses time.Now.
Time func() time.Time
 
// Certificates contains one or more certificate chains
// to present to the other side of the connection.
// Server configurations must include at least one certificate.
Certificates []Certificate
 
// NameToCertificate maps from a certificate name to an element of
// Certificates. Note that a certificate name can be of the form
// '*.example.com' and so doesn't have to be a domain name as such.
// See Config.BuildNameToCertificate
// The nil value causes the first element of Certificates to be used
// for all connections.
NameToCertificate map[string]*Certificate
 
// RootCAs defines the set of root certificate authorities
// that clients use when verifying server certificates.
// If RootCAs is nil, TLS uses the host's root CA set.
RootCAs *x509.CertPool
 
// NextProtos is a list of supported, application level protocols.
NextProtos []string
 
// ServerName is included in the client's handshake to support virtual
// hosting.
ServerName string
 
// ClientAuth determines the server's policy for
// TLS Client Authentication. The default is NoClientCert.
ClientAuth ClientAuthType
 
// ClientCAs defines the set of root certificate authorities
// that servers use if required to verify a client certificate
// by the policy in ClientAuth.
ClientCAs *x509.CertPool
 
// InsecureSkipVerify controls whether a client verifies the
// server's certificate chain and host name.
// If InsecureSkipVerify is true, TLS accepts any certificate
// presented by the server and any host name in that certificate.
// In this mode, TLS is susceptible to man-in-the-middle attacks.
// This should be used only for testing.
InsecureSkipVerify bool
 
// CipherSuites is a list of supported cipher suites. If CipherSuites
// is nil, TLS uses a list of suites supported by the implementation.
CipherSuites []uint16
}
 
func (c *Config) rand() io.Reader {
r := c.Rand
if r == nil {
return rand.Reader
}
return r
}
 
func (c *Config) time() time.Time {
t := c.Time
if t == nil {
t = time.Now
}
return t()
}
 
func (c *Config) rootCAs() *x509.CertPool {
s := c.RootCAs
if s == nil {
s = defaultRoots()
}
return s
}
 
func (c *Config) cipherSuites() []uint16 {
s := c.CipherSuites
if s == nil {
s = defaultCipherSuites()
}
return s
}
 
// getCertificateForName returns the best certificate for the given name,
// defaulting to the first element of c.Certificates if there are no good
// options.
func (c *Config) getCertificateForName(name string) *Certificate {
if len(c.Certificates) == 1 || c.NameToCertificate == nil {
// There's only one choice, so no point doing any work.
return &c.Certificates[0]
}
 
name = strings.ToLower(name)
for len(name) > 0 && name[len(name)-1] == '.' {
name = name[:len(name)-1]
}
 
if cert, ok := c.NameToCertificate[name]; ok {
return cert
}
 
// try replacing labels in the name with wildcards until we get a
// match.
labels := strings.Split(name, ".")
for i := range labels {
labels[i] = "*"
candidate := strings.Join(labels, ".")
if cert, ok := c.NameToCertificate[candidate]; ok {
return cert
}
}
 
// If nothing matches, return the first certificate.
return &c.Certificates[0]
}
 
// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
// from the CommonName and SubjectAlternateName fields of each of the leaf
// certificates.
func (c *Config) BuildNameToCertificate() {
c.NameToCertificate = make(map[string]*Certificate)
for i := range c.Certificates {
cert := &c.Certificates[i]
x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
continue
}
if len(x509Cert.Subject.CommonName) > 0 {
c.NameToCertificate[x509Cert.Subject.CommonName] = cert
}
for _, san := range x509Cert.DNSNames {
c.NameToCertificate[san] = cert
}
}
}
 
// A Certificate is a chain of one or more certificates, leaf first.
type Certificate struct {
Certificate [][]byte
PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey
// OCSPStaple contains an optional OCSP response which will be served
// to clients that request it.
OCSPStaple []byte
// Leaf is the parsed form of the leaf certificate, which may be
// initialized using x509.ParseCertificate to reduce per-handshake
// processing for TLS clients doing client authentication. If nil, the
// leaf certificate will be parsed as needed.
Leaf *x509.Certificate
}
 
// A TLS record.
type record struct {
contentType recordType
major, minor uint8
payload []byte
}
 
type handshakeMessage interface {
marshal() []byte
unmarshal([]byte) bool
}
 
// mutualVersion returns the protocol version to use given the advertised
// version of the peer.
func mutualVersion(vers uint16) (uint16, bool) {
if vers < minVersion {
return 0, false
}
if vers > maxVersion {
vers = maxVersion
}
return vers, true
}
 
var emptyConfig Config
 
func defaultConfig() *Config {
return &emptyConfig
}
 
var once sync.Once
 
func defaultRoots() *x509.CertPool {
once.Do(initDefaults)
return varDefaultRoots
}
 
func defaultCipherSuites() []uint16 {
once.Do(initDefaults)
return varDefaultCipherSuites
}
 
func initDefaults() {
initDefaultRoots()
initDefaultCipherSuites()
}
 
var (
varDefaultRoots *x509.CertPool
varDefaultCipherSuites []uint16
)
 
func initDefaultCipherSuites() {
varDefaultCipherSuites = make([]uint16, len(cipherSuites))
for i, suite := range cipherSuites {
varDefaultCipherSuites[i] = suite.id
}
}
/tls/conn_test.go
0,0 → 1,106
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"testing"
)
 
func TestRoundUp(t *testing.T) {
if roundUp(0, 16) != 0 ||
roundUp(1, 16) != 16 ||
roundUp(15, 16) != 16 ||
roundUp(16, 16) != 16 ||
roundUp(17, 16) != 32 {
t.Error("roundUp broken")
}
}
 
var paddingTests = []struct {
in []byte
good bool
expectedLen int
}{
{[]byte{1, 2, 3, 4, 0}, true, 4},
{[]byte{1, 2, 3, 4, 0, 1}, false, 0},
{[]byte{1, 2, 3, 4, 99, 99}, false, 0},
{[]byte{1, 2, 3, 4, 1, 1}, true, 4},
{[]byte{1, 2, 3, 2, 2, 2}, true, 3},
{[]byte{1, 2, 3, 3, 3, 3}, true, 2},
{[]byte{1, 2, 3, 4, 3, 3}, false, 0},
{[]byte{1, 4, 4, 4, 4, 4}, true, 1},
{[]byte{5, 5, 5, 5, 5, 5}, true, 0},
{[]byte{6, 6, 6, 6, 6, 6}, false, 0},
}
 
func TestRemovePadding(t *testing.T) {
for i, test := range paddingTests {
payload, good := removePadding(test.in)
expectedGood := byte(255)
if !test.good {
expectedGood = 0
}
if good != expectedGood {
t.Errorf("#%d: wrong validity, want:%d got:%d", i, expectedGood, good)
}
if good == 255 && len(payload) != test.expectedLen {
t.Errorf("#%d: got %d, want %d", i, len(payload), test.expectedLen)
}
}
}
 
var certExampleCom = `308201403081eda003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313138353835325a170d3132303933303138353835325a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31a301830160603551d11040f300d820b6578616d706c652e636f6d300b06092a864886f70d0101050341001a0b419d2c74474c6450654e5f10b32bf426ffdf55cad1c52602e7a9151513a3424c70f5960dcd682db0c33769cc1daa3fcdd3db10809d2392ed4a1bf50ced18`
 
var certWildcardExampleCom = `308201423081efa003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303034365a170d3132303933303139303034365a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31c301a30180603551d110411300f820d2a2e6578616d706c652e636f6d300b06092a864886f70d0101050341001676f0c9e7c33c1b656ed5a6476c4e2ee9ec8e62df7407accb1875272b2edd0a22096cb2c22598d11604104d604f810eb4b5987ca6bb319c7e6ce48725c54059`
 
var certFooExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303131345a170d3132303933303139303131345a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104133011820f666f6f2e6578616d706c652e636f6d300b06092a864886f70d010105034100646a2a51f2aa2477add854b462cf5207ba16d3213ffb5d3d0eed473fbf09935019192d1d5b8ca6a2407b424cf04d97c4cd9197c83ecf81f0eab9464a1109d09f`
 
var certDoubleWildcardExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303134315a170d3132303933303139303134315a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104133011820f2a2e2a2e6578616d706c652e636f6d300b06092a864886f70d0101050341001c3de267975f56ef57771c6218ef95ecc65102e57bd1defe6f7efea90d9b26cf40de5bd7ad75e46201c7f2a92aaa3e907451e9409f65e28ddb6db80d726290f6`
 
func TestCertificateSelection(t *testing.T) {
config := Config{
Certificates: []Certificate{
{
Certificate: [][]byte{fromHex(certExampleCom)},
},
{
Certificate: [][]byte{fromHex(certWildcardExampleCom)},
},
{
Certificate: [][]byte{fromHex(certFooExampleCom)},
},
{
Certificate: [][]byte{fromHex(certDoubleWildcardExampleCom)},
},
},
}
 
config.BuildNameToCertificate()
 
pointerToIndex := func(c *Certificate) int {
for i := range config.Certificates {
if c == &config.Certificates[i] {
return i
}
}
return -1
}
 
if n := pointerToIndex(config.getCertificateForName("example.com")); n != 0 {
t.Errorf("example.com returned certificate %d, not 0", n)
}
if n := pointerToIndex(config.getCertificateForName("bar.example.com")); n != 1 {
t.Errorf("bar.example.com returned certificate %d, not 1", n)
}
if n := pointerToIndex(config.getCertificateForName("foo.example.com")); n != 2 {
t.Errorf("foo.example.com returned certificate %d, not 2", n)
}
if n := pointerToIndex(config.getCertificateForName("foo.bar.example.com")); n != 3 {
t.Errorf("foo.bar.example.com returned certificate %d, not 3", n)
}
if n := pointerToIndex(config.getCertificateForName("foo.bar.baz.example.com")); n != 0 {
t.Errorf("foo.bar.baz.example.com returned certificate %d, not 0", n)
}
}
/tls/conn.go
0,0 → 1,849
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// TLS low level connection and record layer
 
package tls
 
import (
"bytes"
"crypto/cipher"
"crypto/subtle"
"crypto/x509"
"errors"
"io"
"net"
"sync"
"time"
)
 
// A Conn represents a secured connection.
// It implements the net.Conn interface.
type Conn struct {
// constant
conn net.Conn
isClient bool
 
// constant after handshake; protected by handshakeMutex
handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
vers uint16 // TLS version
haveVers bool // version has been negotiated
config *Config // configuration passed to constructor
handshakeComplete bool
cipherSuite uint16
ocspResponse []byte // stapled OCSP response
peerCertificates []*x509.Certificate
// verifiedChains contains the certificate chains that we built, as
// opposed to the ones presented by the server.
verifiedChains [][]*x509.Certificate
// serverName contains the server name indicated by the client, if any.
serverName string
 
clientProtocol string
clientProtocolFallback bool
 
// first permanent error
errMutex sync.Mutex
err error
 
// input/output
in, out halfConn // in.Mutex < out.Mutex
rawInput *block // raw input, right off the wire
input *block // application data waiting to be read
hand bytes.Buffer // handshake data waiting to be read
 
tmp [16]byte
}
 
func (c *Conn) setError(err error) error {
c.errMutex.Lock()
defer c.errMutex.Unlock()
 
if c.err == nil {
c.err = err
}
return err
}
 
func (c *Conn) error() error {
c.errMutex.Lock()
defer c.errMutex.Unlock()
 
return c.err
}
 
// Access to net.Conn methods.
// Cannot just embed net.Conn because that would
// export the struct field too.
 
// LocalAddr returns the local network address.
func (c *Conn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
 
// RemoteAddr returns the remote network address.
func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
 
// SetDeadline sets the read deadline associated with the connection.
// There is no write deadline.
// A zero value for t means Read will not time out.
func (c *Conn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
 
// SetReadDeadline sets the read deadline on the underlying connection.
// A zero value for t means Read will not time out.
func (c *Conn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
 
// SetWriteDeadline exists to satisfy the net.Conn interface
// but is not implemented by TLS. It always returns an error.
func (c *Conn) SetWriteDeadline(t time.Time) error {
return errors.New("TLS does not support SetWriteDeadline")
}
 
// A halfConn represents one direction of the record layer
// connection, either sending or receiving.
type halfConn struct {
sync.Mutex
version uint16 // protocol version
cipher interface{} // cipher algorithm
mac macFunction
seq [8]byte // 64-bit sequence number
bfree *block // list of free blocks
 
nextCipher interface{} // next encryption state
nextMac macFunction // next MAC algorithm
 
// used to save allocating a new buffer for each MAC.
inDigestBuf, outDigestBuf []byte
}
 
// prepareCipherSpec sets the encryption and MAC states
// that a subsequent changeCipherSpec will use.
func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
hc.version = version
hc.nextCipher = cipher
hc.nextMac = mac
}
 
// changeCipherSpec changes the encryption and MAC states
// to the ones previously passed to prepareCipherSpec.
func (hc *halfConn) changeCipherSpec() error {
if hc.nextCipher == nil {
return alertInternalError
}
hc.cipher = hc.nextCipher
hc.mac = hc.nextMac
hc.nextCipher = nil
hc.nextMac = nil
return nil
}
 
// incSeq increments the sequence number.
func (hc *halfConn) incSeq() {
for i := 7; i >= 0; i-- {
hc.seq[i]++
if hc.seq[i] != 0 {
return
}
}
 
// Not allowed to let sequence number wrap.
// Instead, must renegotiate before it does.
// Not likely enough to bother.
panic("TLS: sequence number wraparound")
}
 
// resetSeq resets the sequence number to zero.
func (hc *halfConn) resetSeq() {
for i := range hc.seq {
hc.seq[i] = 0
}
}
 
// removePadding returns an unpadded slice, in constant time, which is a prefix
// of the input. It also returns a byte which is equal to 255 if the padding
// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
func removePadding(payload []byte) ([]byte, byte) {
if len(payload) < 1 {
return payload, 0
}
 
paddingLen := payload[len(payload)-1]
t := uint(len(payload)-1) - uint(paddingLen)
// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
good := byte(int32(^t) >> 31)
 
toCheck := 255 // the maximum possible padding length
// The length of the padded data is public, so we can use an if here
if toCheck+1 > len(payload) {
toCheck = len(payload) - 1
}
 
for i := 0; i < toCheck; i++ {
t := uint(paddingLen) - uint(i)
// if i <= paddingLen then the MSB of t is zero
mask := byte(int32(^t) >> 31)
b := payload[len(payload)-1-i]
good &^= mask&paddingLen ^ mask&b
}
 
// We AND together the bits of good and replicate the result across
// all the bits.
good &= good << 4
good &= good << 2
good &= good << 1
good = uint8(int8(good) >> 7)
 
toRemove := good&paddingLen + 1
return payload[:len(payload)-int(toRemove)], good
}
 
// removePaddingSSL30 is a replacement for removePadding in the case that the
// protocol version is SSLv3. In this version, the contents of the padding
// are random and cannot be checked.
func removePaddingSSL30(payload []byte) ([]byte, byte) {
if len(payload) < 1 {
return payload, 0
}
 
paddingLen := int(payload[len(payload)-1]) + 1
if paddingLen > len(payload) {
return payload, 0
}
 
return payload[:len(payload)-paddingLen], 255
}
 
func roundUp(a, b int) int {
return a + (b-a%b)%b
}
 
// decrypt checks and strips the mac and decrypts the data in b.
func (hc *halfConn) decrypt(b *block) (bool, alert) {
// pull out payload
payload := b.data[recordHeaderLen:]
 
macSize := 0
if hc.mac != nil {
macSize = hc.mac.Size()
}
 
paddingGood := byte(255)
 
// decrypt
if hc.cipher != nil {
switch c := hc.cipher.(type) {
case cipher.Stream:
c.XORKeyStream(payload, payload)
case cipher.BlockMode:
blockSize := c.BlockSize()
 
if len(payload)%blockSize != 0 || len(payload) < roundUp(macSize+1, blockSize) {
return false, alertBadRecordMAC
}
 
c.CryptBlocks(payload, payload)
if hc.version == versionSSL30 {
payload, paddingGood = removePaddingSSL30(payload)
} else {
payload, paddingGood = removePadding(payload)
}
b.resize(recordHeaderLen + len(payload))
 
// note that we still have a timing side-channel in the
// MAC check, below. An attacker can align the record
// so that a correct padding will cause one less hash
// block to be calculated. Then they can iteratively
// decrypt a record by breaking each byte. See
// "Password Interception in a SSL/TLS Channel", Brice
// Canvel et al.
//
// However, our behavior matches OpenSSL, so we leak
// only as much as they do.
default:
panic("unknown cipher type")
}
}
 
// check, strip mac
if hc.mac != nil {
if len(payload) < macSize {
return false, alertBadRecordMAC
}
 
// strip mac off payload, b.data
n := len(payload) - macSize
b.data[3] = byte(n >> 8)
b.data[4] = byte(n)
b.resize(recordHeaderLen + n)
remoteMAC := payload[n:]
localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data)
hc.incSeq()
 
if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
return false, alertBadRecordMAC
}
hc.inDigestBuf = localMAC
}
 
return true, 0
}
 
// padToBlockSize calculates the needed padding block, if any, for a payload.
// On exit, prefix aliases payload and extends to the end of the last full
// block of payload. finalBlock is a fresh slice which contains the contents of
// any suffix of payload as well as the needed padding to make finalBlock a
// full block.
func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
overrun := len(payload) % blockSize
paddingLen := blockSize - overrun
prefix = payload[:len(payload)-overrun]
finalBlock = make([]byte, blockSize)
copy(finalBlock, payload[len(payload)-overrun:])
for i := overrun; i < blockSize; i++ {
finalBlock[i] = byte(paddingLen - 1)
}
return
}
 
// encrypt encrypts and macs the data in b.
func (hc *halfConn) encrypt(b *block) (bool, alert) {
// mac
if hc.mac != nil {
mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data)
hc.incSeq()
 
n := len(b.data)
b.resize(n + len(mac))
copy(b.data[n:], mac)
hc.outDigestBuf = mac
}
 
payload := b.data[recordHeaderLen:]
 
// encrypt
if hc.cipher != nil {
switch c := hc.cipher.(type) {
case cipher.Stream:
c.XORKeyStream(payload, payload)
case cipher.BlockMode:
prefix, finalBlock := padToBlockSize(payload, c.BlockSize())
b.resize(recordHeaderLen + len(prefix) + len(finalBlock))
c.CryptBlocks(b.data[recordHeaderLen:], prefix)
c.CryptBlocks(b.data[recordHeaderLen+len(prefix):], finalBlock)
default:
panic("unknown cipher type")
}
}
 
// update length to include MAC and any block padding needed.
n := len(b.data) - recordHeaderLen
b.data[3] = byte(n >> 8)
b.data[4] = byte(n)
 
return true, 0
}
 
// A block is a simple data buffer.
type block struct {
data []byte
off int // index for Read
link *block
}
 
// resize resizes block to be n bytes, growing if necessary.
func (b *block) resize(n int) {
if n > cap(b.data) {
b.reserve(n)
}
b.data = b.data[0:n]
}
 
// reserve makes sure that block contains a capacity of at least n bytes.
func (b *block) reserve(n int) {
if cap(b.data) >= n {
return
}
m := cap(b.data)
if m == 0 {
m = 1024
}
for m < n {
m *= 2
}
data := make([]byte, len(b.data), m)
copy(data, b.data)
b.data = data
}
 
// readFromUntil reads from r into b until b contains at least n bytes
// or else returns an error.
func (b *block) readFromUntil(r io.Reader, n int) error {
// quick case
if len(b.data) >= n {
return nil
}
 
// read until have enough.
b.reserve(n)
for {
m, err := r.Read(b.data[len(b.data):cap(b.data)])
b.data = b.data[0 : len(b.data)+m]
if len(b.data) >= n {
break
}
if err != nil {
return err
}
}
return nil
}
 
func (b *block) Read(p []byte) (n int, err error) {
n = copy(p, b.data[b.off:])
b.off += n
return
}
 
// newBlock allocates a new block, from hc's free list if possible.
func (hc *halfConn) newBlock() *block {
b := hc.bfree
if b == nil {
return new(block)
}
hc.bfree = b.link
b.link = nil
b.resize(0)
return b
}
 
// freeBlock returns a block to hc's free list.
// The protocol is such that each side only has a block or two on
// its free list at a time, so there's no need to worry about
// trimming the list, etc.
func (hc *halfConn) freeBlock(b *block) {
b.link = hc.bfree
hc.bfree = b
}
 
// splitBlock splits a block after the first n bytes,
// returning a block with those n bytes and a
// block with the remainder. the latter may be nil.
func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) {
if len(b.data) <= n {
return b, nil
}
bb := hc.newBlock()
bb.resize(len(b.data) - n)
copy(bb.data, b.data[n:])
b.data = b.data[0:n]
return b, bb
}
 
// readRecord reads the next TLS record from the connection
// and updates the record layer state.
// c.in.Mutex <= L; c.input == nil.
func (c *Conn) readRecord(want recordType) error {
// Caller must be in sync with connection:
// handshake data if handshake not yet completed,
// else application data. (We don't support renegotiation.)
switch want {
default:
return c.sendAlert(alertInternalError)
case recordTypeHandshake, recordTypeChangeCipherSpec:
if c.handshakeComplete {
return c.sendAlert(alertInternalError)
}
case recordTypeApplicationData:
if !c.handshakeComplete {
return c.sendAlert(alertInternalError)
}
}
 
Again:
if c.rawInput == nil {
c.rawInput = c.in.newBlock()
}
b := c.rawInput
 
// Read header, payload.
if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
// RFC suggests that EOF without an alertCloseNotify is
// an error, but popular web sites seem to do this,
// so we can't make it an error.
// if err == io.EOF {
// err = io.ErrUnexpectedEOF
// }
if e, ok := err.(net.Error); !ok || !e.Temporary() {
c.setError(err)
}
return err
}
typ := recordType(b.data[0])
vers := uint16(b.data[1])<<8 | uint16(b.data[2])
n := int(b.data[3])<<8 | int(b.data[4])
if c.haveVers && vers != c.vers {
return c.sendAlert(alertProtocolVersion)
}
if n > maxCiphertext {
return c.sendAlert(alertRecordOverflow)
}
if !c.haveVers {
// First message, be extra suspicious:
// this might not be a TLS client.
// Bail out before reading a full 'body', if possible.
// The current max version is 3.1.
// If the version is >= 16.0, it's probably not real.
// Similarly, a clientHello message encodes in
// well under a kilobyte. If the length is >= 12 kB,
// it's probably not real.
if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
return c.sendAlert(alertUnexpectedMessage)
}
}
if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
if e, ok := err.(net.Error); !ok || !e.Temporary() {
c.setError(err)
}
return err
}
 
// Process message.
b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
b.off = recordHeaderLen
if ok, err := c.in.decrypt(b); !ok {
return c.sendAlert(err)
}
data := b.data[b.off:]
if len(data) > maxPlaintext {
c.sendAlert(alertRecordOverflow)
c.in.freeBlock(b)
return c.error()
}
 
switch typ {
default:
c.sendAlert(alertUnexpectedMessage)
 
case recordTypeAlert:
if len(data) != 2 {
c.sendAlert(alertUnexpectedMessage)
break
}
if alert(data[1]) == alertCloseNotify {
c.setError(io.EOF)
break
}
switch data[0] {
case alertLevelWarning:
// drop on the floor
c.in.freeBlock(b)
goto Again
case alertLevelError:
c.setError(&net.OpError{Op: "remote error", Err: alert(data[1])})
default:
c.sendAlert(alertUnexpectedMessage)
}
 
case recordTypeChangeCipherSpec:
if typ != want || len(data) != 1 || data[0] != 1 {
c.sendAlert(alertUnexpectedMessage)
break
}
err := c.in.changeCipherSpec()
if err != nil {
c.sendAlert(err.(alert))
}
 
case recordTypeApplicationData:
if typ != want {
c.sendAlert(alertUnexpectedMessage)
break
}
c.input = b
b = nil
 
case recordTypeHandshake:
// TODO(rsc): Should at least pick off connection close.
if typ != want {
return c.sendAlert(alertNoRenegotiation)
}
c.hand.Write(data)
}
 
if b != nil {
c.in.freeBlock(b)
}
return c.error()
}
 
// sendAlert sends a TLS alert message.
// c.out.Mutex <= L.
func (c *Conn) sendAlertLocked(err alert) error {
c.tmp[0] = alertLevelError
if err == alertNoRenegotiation {
c.tmp[0] = alertLevelWarning
}
c.tmp[1] = byte(err)
c.writeRecord(recordTypeAlert, c.tmp[0:2])
// closeNotify is a special case in that it isn't an error:
if err != alertCloseNotify {
return c.setError(&net.OpError{Op: "local error", Err: err})
}
return nil
}
 
// sendAlert sends a TLS alert message.
// L < c.out.Mutex.
func (c *Conn) sendAlert(err alert) error {
c.out.Lock()
defer c.out.Unlock()
return c.sendAlertLocked(err)
}
 
// writeRecord writes a TLS record with the given type and payload
// to the connection and updates the record layer state.
// c.out.Mutex <= L.
func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
b := c.out.newBlock()
for len(data) > 0 {
m := len(data)
if m > maxPlaintext {
m = maxPlaintext
}
b.resize(recordHeaderLen + m)
b.data[0] = byte(typ)
vers := c.vers
if vers == 0 {
vers = maxVersion
}
b.data[1] = byte(vers >> 8)
b.data[2] = byte(vers)
b.data[3] = byte(m >> 8)
b.data[4] = byte(m)
copy(b.data[recordHeaderLen:], data)
c.out.encrypt(b)
_, err = c.conn.Write(b.data)
if err != nil {
break
}
n += m
data = data[m:]
}
c.out.freeBlock(b)
 
if typ == recordTypeChangeCipherSpec {
err = c.out.changeCipherSpec()
if err != nil {
// Cannot call sendAlert directly,
// because we already hold c.out.Mutex.
c.tmp[0] = alertLevelError
c.tmp[1] = byte(err.(alert))
c.writeRecord(recordTypeAlert, c.tmp[0:2])
c.err = &net.OpError{Op: "local error", Err: err}
return n, c.err
}
}
return
}
 
// readHandshake reads the next handshake message from
// the record layer.
// c.in.Mutex < L; c.out.Mutex < L.
func (c *Conn) readHandshake() (interface{}, error) {
for c.hand.Len() < 4 {
if c.err != nil {
return nil, c.err
}
if err := c.readRecord(recordTypeHandshake); err != nil {
return nil, err
}
}
 
data := c.hand.Bytes()
n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
if n > maxHandshake {
c.sendAlert(alertInternalError)
return nil, c.err
}
for c.hand.Len() < 4+n {
if c.err != nil {
return nil, c.err
}
if err := c.readRecord(recordTypeHandshake); err != nil {
return nil, err
}
}
data = c.hand.Next(4 + n)
var m handshakeMessage
switch data[0] {
case typeClientHello:
m = new(clientHelloMsg)
case typeServerHello:
m = new(serverHelloMsg)
case typeCertificate:
m = new(certificateMsg)
case typeCertificateRequest:
m = new(certificateRequestMsg)
case typeCertificateStatus:
m = new(certificateStatusMsg)
case typeServerKeyExchange:
m = new(serverKeyExchangeMsg)
case typeServerHelloDone:
m = new(serverHelloDoneMsg)
case typeClientKeyExchange:
m = new(clientKeyExchangeMsg)
case typeCertificateVerify:
m = new(certificateVerifyMsg)
case typeNextProtocol:
m = new(nextProtoMsg)
case typeFinished:
m = new(finishedMsg)
default:
c.sendAlert(alertUnexpectedMessage)
return nil, alertUnexpectedMessage
}
 
// The handshake message unmarshallers
// expect to be able to keep references to data,
// so pass in a fresh copy that won't be overwritten.
data = append([]byte(nil), data...)
 
if !m.unmarshal(data) {
c.sendAlert(alertUnexpectedMessage)
return nil, alertUnexpectedMessage
}
return m, nil
}
 
// Write writes data to the connection.
func (c *Conn) Write(b []byte) (n int, err error) {
if err = c.Handshake(); err != nil {
return
}
 
c.out.Lock()
defer c.out.Unlock()
 
if !c.handshakeComplete {
return 0, alertInternalError
}
if c.err != nil {
return 0, c.err
}
return c.writeRecord(recordTypeApplicationData, b)
}
 
// Read can be made to time out and return a net.Error with Timeout() == true
// after a fixed time limit; see SetDeadline and SetReadDeadline.
func (c *Conn) Read(b []byte) (n int, err error) {
if err = c.Handshake(); err != nil {
return
}
 
c.in.Lock()
defer c.in.Unlock()
 
for c.input == nil && c.err == nil {
if err := c.readRecord(recordTypeApplicationData); err != nil {
// Soft error, like EAGAIN
return 0, err
}
}
if c.err != nil {
return 0, c.err
}
n, err = c.input.Read(b)
if c.input.off >= len(c.input.data) {
c.in.freeBlock(c.input)
c.input = nil
}
return n, nil
}
 
// Close closes the connection.
func (c *Conn) Close() error {
var alertErr error
 
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
if c.handshakeComplete {
alertErr = c.sendAlert(alertCloseNotify)
}
 
if err := c.conn.Close(); err != nil {
return err
}
return alertErr
}
 
// Handshake runs the client or server handshake
// protocol if it has not yet been run.
// Most uses of this package need not call Handshake
// explicitly: the first Read or Write will call it automatically.
func (c *Conn) Handshake() error {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
if err := c.error(); err != nil {
return err
}
if c.handshakeComplete {
return nil
}
if c.isClient {
return c.clientHandshake()
}
return c.serverHandshake()
}
 
// ConnectionState returns basic TLS details about the connection.
func (c *Conn) ConnectionState() ConnectionState {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
 
var state ConnectionState
state.HandshakeComplete = c.handshakeComplete
if c.handshakeComplete {
state.NegotiatedProtocol = c.clientProtocol
state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
state.CipherSuite = c.cipherSuite
state.PeerCertificates = c.peerCertificates
state.VerifiedChains = c.verifiedChains
state.ServerName = c.serverName
}
 
return state
}
 
// OCSPResponse returns the stapled OCSP response from the TLS server, if
// any. (Only valid for client connections.)
func (c *Conn) OCSPResponse() []byte {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
 
return c.ocspResponse
}
 
// VerifyHostname checks that the peer certificate chain is valid for
// connecting to host. If so, it returns nil; if not, it returns an error
// describing the problem.
func (c *Conn) VerifyHostname(host string) error {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
if !c.isClient {
return errors.New("VerifyHostname called on TLS server connection")
}
if !c.handshakeComplete {
return errors.New("TLS handshake has not yet been performed")
}
return c.peerCertificates[0].VerifyHostname(host)
}
/tls/root_windows.go
0,0 → 1,47
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"crypto/x509"
"syscall"
"unsafe"
)
 
func loadStore(roots *x509.CertPool, name string) {
store, err := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name))
if err != nil {
return
}
defer syscall.CertCloseStore(store, 0)
 
var cert *syscall.CertContext
for {
cert, err = syscall.CertEnumCertificatesInStore(store, cert)
if err != nil {
return
}
 
buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:]
// ParseCertificate requires its own copy of certificate data to keep.
buf2 := make([]byte, cert.Length)
copy(buf2, buf)
if c, err := x509.ParseCertificate(buf2); err == nil {
roots.AddCert(c)
}
}
}
 
func initDefaultRoots() {
roots := x509.NewCertPool()
 
// Roots
loadStore(roots, "ROOT")
 
// Intermediates
loadStore(roots, "CA")
 
varDefaultRoots = roots
}
/tls/tls.go
0,0 → 1,186
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package tls partially implements the TLS 1.1 protocol, as specified in RFC
// 4346.
package tls
 
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"io/ioutil"
"net"
"strings"
)
 
// Server returns a new TLS server side connection
// using conn as the underlying transport.
// The configuration config must be non-nil and must have
// at least one certificate.
func Server(conn net.Conn, config *Config) *Conn {
return &Conn{conn: conn, config: config}
}
 
// Client returns a new TLS client side connection
// using conn as the underlying transport.
// Client interprets a nil configuration as equivalent to
// the zero configuration; see the documentation of Config
// for the defaults.
func Client(conn net.Conn, config *Config) *Conn {
return &Conn{conn: conn, config: config, isClient: true}
}
 
// A listener implements a network listener (net.Listener) for TLS connections.
type listener struct {
net.Listener
config *Config
}
 
// Accept waits for and returns the next incoming TLS connection.
// The returned connection c is a *tls.Conn.
func (l *listener) Accept() (c net.Conn, err error) {
c, err = l.Listener.Accept()
if err != nil {
return
}
c = Server(c, l.config)
return
}
 
// NewListener creates a Listener which accepts connections from an inner
// Listener and wraps each connection with Server.
// The configuration config must be non-nil and must have
// at least one certificate.
func NewListener(inner net.Listener, config *Config) net.Listener {
l := new(listener)
l.Listener = inner
l.config = config
return l
}
 
// Listen creates a TLS listener accepting connections on the
// given network address using net.Listen.
// The configuration config must be non-nil and must have
// at least one certificate.
func Listen(network, laddr string, config *Config) (net.Listener, error) {
if config == nil || len(config.Certificates) == 0 {
return nil, errors.New("tls.Listen: no certificates in configuration")
}
l, err := net.Listen(network, laddr)
if err != nil {
return nil, err
}
return NewListener(l, config), nil
}
 
// Dial connects to the given network address using net.Dial
// and then initiates a TLS handshake, returning the resulting
// TLS connection.
// Dial interprets a nil configuration as equivalent to
// the zero configuration; see the documentation of Config
// for the defaults.
func Dial(network, addr string, config *Config) (*Conn, error) {
raddr := addr
c, err := net.Dial(network, raddr)
if err != nil {
return nil, err
}
 
colonPos := strings.LastIndex(raddr, ":")
if colonPos == -1 {
colonPos = len(raddr)
}
hostname := raddr[:colonPos]
 
if config == nil {
config = defaultConfig()
}
if config.ServerName != "" {
// Make a copy to avoid polluting argument or default.
c := *config
c.ServerName = hostname
config = &c
}
conn := Client(c, config)
if err = conn.Handshake(); err != nil {
c.Close()
return nil, err
}
return conn, nil
}
 
// LoadX509KeyPair reads and parses a public/private key pair from a pair of
// files. The files must contain PEM encoded data.
func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
certPEMBlock, err := ioutil.ReadFile(certFile)
if err != nil {
return
}
keyPEMBlock, err := ioutil.ReadFile(keyFile)
if err != nil {
return
}
return X509KeyPair(certPEMBlock, keyPEMBlock)
}
 
// X509KeyPair parses a public/private key pair from a pair of
// PEM encoded data.
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) {
var certDERBlock *pem.Block
for {
certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
if certDERBlock == nil {
break
}
if certDERBlock.Type == "CERTIFICATE" {
cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
}
}
 
if len(cert.Certificate) == 0 {
err = errors.New("crypto/tls: failed to parse certificate PEM data")
return
}
 
keyDERBlock, _ := pem.Decode(keyPEMBlock)
if keyDERBlock == nil {
err = errors.New("crypto/tls: failed to parse key PEM data")
return
}
 
// OpenSSL 0.9.8 generates PKCS#1 private keys by default, while
// OpenSSL 1.0.0 generates PKCS#8 keys. We try both.
var key *rsa.PrivateKey
if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err != nil {
var privKey interface{}
if privKey, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err != nil {
err = errors.New("crypto/tls: failed to parse key: " + err.Error())
return
}
 
var ok bool
if key, ok = privKey.(*rsa.PrivateKey); !ok {
err = errors.New("crypto/tls: found non-RSA private key in PKCS#8 wrapping")
return
}
}
 
cert.PrivateKey = key
 
// We don't need to parse the public key for TLS, but we so do anyway
// to check that it looks sane and matches the private key.
x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return
}
 
if x509Cert.PublicKeyAlgorithm != x509.RSA || x509Cert.PublicKey.(*rsa.PublicKey).N.Cmp(key.PublicKey.N) != 0 {
err = errors.New("crypto/tls: private key does not match public key")
return
}
 
return
}
/tls/cipher_suites.go
0,0 → 1,188
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import (
"crypto/aes"
"crypto/cipher"
"crypto/des"
"crypto/hmac"
"crypto/rc4"
"crypto/sha1"
"crypto/x509"
"hash"
)
 
// a keyAgreement implements the client and server side of a TLS key agreement
// protocol by generating and processing key exchange messages.
type keyAgreement interface {
// On the server side, the first two methods are called in order.
 
// In the case that the key agreement protocol doesn't use a
// ServerKeyExchange message, generateServerKeyExchange can return nil,
// nil.
generateServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
processClientKeyExchange(*Config, *clientKeyExchangeMsg, uint16) ([]byte, error)
 
// On the client side, the next two methods are called in order.
 
// This method may not be called if the server doesn't send a
// ServerKeyExchange message.
processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
}
 
// A cipherSuite is a specific combination of key agreement, cipher and MAC
// function. All cipher suites currently assume RSA key agreement.
type cipherSuite struct {
id uint16
// the lengths, in bytes, of the key material needed for each component.
keyLen int
macLen int
ivLen int
ka func() keyAgreement
// If elliptic is set, a server will only consider this ciphersuite if
// the ClientHello indicated that the client supports an elliptic curve
// and point format that we can handle.
elliptic bool
cipher func(key, iv []byte, isRead bool) interface{}
mac func(version uint16, macKey []byte) macFunction
}
 
var cipherSuites = []*cipherSuite{
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
}
 
func cipherRC4(key, iv []byte, isRead bool) interface{} {
cipher, _ := rc4.NewCipher(key)
return cipher
}
 
func cipher3DES(key, iv []byte, isRead bool) interface{} {
block, _ := des.NewTripleDESCipher(key)
if isRead {
return cipher.NewCBCDecrypter(block, iv)
}
return cipher.NewCBCEncrypter(block, iv)
}
 
func cipherAES(key, iv []byte, isRead bool) interface{} {
block, _ := aes.NewCipher(key)
if isRead {
return cipher.NewCBCDecrypter(block, iv)
}
return cipher.NewCBCEncrypter(block, iv)
}
 
// macSHA1 returns a macFunction for the given protocol version.
func macSHA1(version uint16, key []byte) macFunction {
if version == versionSSL30 {
mac := ssl30MAC{
h: sha1.New(),
key: make([]byte, len(key)),
}
copy(mac.key, key)
return mac
}
return tls10MAC{hmac.New(sha1.New, key)}
}
 
type macFunction interface {
Size() int
MAC(digestBuf, seq, data []byte) []byte
}
 
// ssl30MAC implements the SSLv3 MAC function, as defined in
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
type ssl30MAC struct {
h hash.Hash
key []byte
}
 
func (s ssl30MAC) Size() int {
return s.h.Size()
}
 
var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
 
var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
 
func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte {
padLength := 48
if s.h.Size() == 20 {
padLength = 40
}
 
s.h.Reset()
s.h.Write(s.key)
s.h.Write(ssl30Pad1[:padLength])
s.h.Write(seq)
s.h.Write(record[:1])
s.h.Write(record[3:5])
s.h.Write(record[recordHeaderLen:])
digestBuf = s.h.Sum(digestBuf[:0])
 
s.h.Reset()
s.h.Write(s.key)
s.h.Write(ssl30Pad2[:padLength])
s.h.Write(digestBuf)
return s.h.Sum(digestBuf[:0])
}
 
// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
type tls10MAC struct {
h hash.Hash
}
 
func (s tls10MAC) Size() int {
return s.h.Size()
}
 
func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte {
s.h.Reset()
s.h.Write(seq)
s.h.Write(record)
return s.h.Sum(digestBuf[:0])
}
 
func rsaKA() keyAgreement {
return rsaKeyAgreement{}
}
 
func ecdheRSAKA() keyAgreement {
return new(ecdheRSAKeyAgreement)
}
 
// mutualCipherSuite returns a cipherSuite given a list of supported
// ciphersuites and the id requested by the peer.
func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
for _, id := range have {
if id == want {
for _, suite := range cipherSuites {
if suite.id == want {
return suite
}
}
return nil
}
}
return nil
}
 
// A list of the possible cipher suite ids. Taken from
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
const (
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
)
/tls/alert.go
0,0 → 1,77
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package tls
 
import "strconv"
 
type alert uint8
 
const (
// alert level
alertLevelWarning = 1
alertLevelError = 2
)
 
const (
alertCloseNotify alert = 0
alertUnexpectedMessage alert = 10
alertBadRecordMAC alert = 20
alertDecryptionFailed alert = 21
alertRecordOverflow alert = 22
alertDecompressionFailure alert = 30
alertHandshakeFailure alert = 40
alertBadCertificate alert = 42
alertUnsupportedCertificate alert = 43
alertCertificateRevoked alert = 44
alertCertificateExpired alert = 45
alertCertificateUnknown alert = 46
alertIllegalParameter alert = 47
alertUnknownCA alert = 48
alertAccessDenied alert = 49
alertDecodeError alert = 50
alertDecryptError alert = 51
alertProtocolVersion alert = 70
alertInsufficientSecurity alert = 71
alertInternalError alert = 80
alertUserCanceled alert = 90
alertNoRenegotiation alert = 100
)
 
var alertText = map[alert]string{
alertCloseNotify: "close notify",
alertUnexpectedMessage: "unexpected message",
alertBadRecordMAC: "bad record MAC",
alertDecryptionFailed: "decryption failed",
alertRecordOverflow: "record overflow",
alertDecompressionFailure: "decompression failure",
alertHandshakeFailure: "handshake failure",
alertBadCertificate: "bad certificate",
alertUnsupportedCertificate: "unsupported certificate",
alertCertificateRevoked: "revoked certificate",
alertCertificateExpired: "expired certificate",
alertCertificateUnknown: "unknown certificate",
alertIllegalParameter: "illegal parameter",
alertUnknownCA: "unknown certificate authority",
alertAccessDenied: "access denied",
alertDecodeError: "error decoding message",
alertDecryptError: "error decrypting message",
alertProtocolVersion: "protocol version not supported",
alertInsufficientSecurity: "insufficient security level",
alertInternalError: "internal error",
alertUserCanceled: "user canceled",
alertNoRenegotiation: "no renegotiation",
}
 
func (e alert) String() string {
s, ok := alertText[e]
if ok {
return s
}
return "alert(" + strconv.Itoa(int(e)) + ")"
}
 
func (e alert) Error() string {
return e.String()
}
/tls/generate_cert.go
0,0 → 1,72
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Generate a self-signed X.509 certificate for a TLS server. Outputs to
// 'cert.pem' and 'key.pem' and will overwrite existing files.
 
package main
 
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"flag"
"log"
"math/big"
"os"
"time"
)
 
var hostName *string = flag.String("host", "127.0.0.1", "Hostname to generate a certificate for")
 
func main() {
flag.Parse()
 
priv, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
log.Fatalf("failed to generate private key: %s", err)
return
}
 
now := time.Now()
 
template := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
Subject: pkix.Name{
CommonName: *hostName,
Organization: []string{"Acme Co"},
},
NotBefore: now.Add(-5 * time.Minute).UTC(),
NotAfter: now.AddDate(1, 0, 0).UTC(), // valid for 1 year.
 
SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
}
 
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
log.Fatalf("Failed to create certificate: %s", err)
return
}
 
certOut, err := os.Create("cert.pem")
if err != nil {
log.Fatalf("failed to open cert.pem for writing: %s", err)
return
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
log.Print("written cert.pem\n")
 
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Print("failed to open key.pem for writing:", err)
return
}
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
keyOut.Close()
log.Print("written key.pem\n")
}
/sha512/sha512block.go
0,0 → 1,144
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// SHA512 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
 
package sha512
 
var _K = []uint64{
0x428a2f98d728ae22,
0x7137449123ef65cd,
0xb5c0fbcfec4d3b2f,
0xe9b5dba58189dbbc,
0x3956c25bf348b538,
0x59f111f1b605d019,
0x923f82a4af194f9b,
0xab1c5ed5da6d8118,
0xd807aa98a3030242,
0x12835b0145706fbe,
0x243185be4ee4b28c,
0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f,
0x80deb1fe3b1696b1,
0x9bdc06a725c71235,
0xc19bf174cf692694,
0xe49b69c19ef14ad2,
0xefbe4786384f25e3,
0x0fc19dc68b8cd5b5,
0x240ca1cc77ac9c65,
0x2de92c6f592b0275,
0x4a7484aa6ea6e483,
0x5cb0a9dcbd41fbd4,
0x76f988da831153b5,
0x983e5152ee66dfab,
0xa831c66d2db43210,
0xb00327c898fb213f,
0xbf597fc7beef0ee4,
0xc6e00bf33da88fc2,
0xd5a79147930aa725,
0x06ca6351e003826f,
0x142929670a0e6e70,
0x27b70a8546d22ffc,
0x2e1b21385c26c926,
0x4d2c6dfc5ac42aed,
0x53380d139d95b3df,
0x650a73548baf63de,
0x766a0abb3c77b2a8,
0x81c2c92e47edaee6,
0x92722c851482353b,
0xa2bfe8a14cf10364,
0xa81a664bbc423001,
0xc24b8b70d0f89791,
0xc76c51a30654be30,
0xd192e819d6ef5218,
0xd69906245565a910,
0xf40e35855771202a,
0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8,
0x1e376c085141ab53,
0x2748774cdf8eeb99,
0x34b0bcb5e19b48a8,
0x391c0cb3c5c95a63,
0x4ed8aa4ae3418acb,
0x5b9cca4f7763e373,
0x682e6ff3d6b2b8a3,
0x748f82ee5defb2fc,
0x78a5636f43172f60,
0x84c87814a1f0ab72,
0x8cc702081a6439ec,
0x90befffa23631e28,
0xa4506cebde82bde9,
0xbef9a3f7b2c67915,
0xc67178f2e372532b,
0xca273eceea26619c,
0xd186b8c721c0c207,
0xeada7dd6cde0eb1e,
0xf57d4f7fee6ed178,
0x06f067aa72176fba,
0x0a637dc5a2c898a6,
0x113f9804bef90dae,
0x1b710b35131c471b,
0x28db77f523047d84,
0x32caab7b40c72493,
0x3c9ebe0a15c9bebc,
0x431d67c49c100d4c,
0x4cc5d4becb3e42b6,
0x597f299cfc657e2a,
0x5fcb6fab3ad6faec,
0x6c44198c4a475817,
}
 
func _Block(dig *digest, p []byte) int {
var w [80]uint64
n := 0
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= _Chunk {
for i := 0; i < 16; i++ {
j := i * 8
w[i] = uint64(p[j])<<56 | uint64(p[j+1])<<48 | uint64(p[j+2])<<40 | uint64(p[j+3])<<32 |
uint64(p[j+4])<<24 | uint64(p[j+5])<<16 | uint64(p[j+6])<<8 | uint64(p[j+7])
}
for i := 16; i < 80; i++ {
t1 := (w[i-2]>>19 | w[i-2]<<(64-19)) ^ (w[i-2]>>61 | w[i-2]<<(64-61)) ^ (w[i-2] >> 6)
 
t2 := (w[i-15]>>1 | w[i-15]<<(64-1)) ^ (w[i-15]>>8 | w[i-15]<<(64-8)) ^ (w[i-15] >> 7)
 
w[i] = t1 + w[i-7] + t2 + w[i-16]
}
 
a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
 
for i := 0; i < 80; i++ {
t1 := h + ((e>>14 | e<<(64-14)) ^ (e>>18 | e<<(64-18)) ^ (e>>41 | e<<(64-41))) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
 
t2 := ((a>>28 | a<<(64-28)) ^ (a>>34 | a<<(64-34)) ^ (a>>39 | a<<(64-39))) + ((a & b) ^ (a & c) ^ (b & c))
 
h = g
g = f
f = e
e = d + t1
d = c
c = b
b = a
a = t1 + t2
}
 
h0 += a
h1 += b
h2 += c
h3 += d
h4 += e
h5 += f
h6 += g
h7 += h
 
p = p[_Chunk:]
n += _Chunk
}
 
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
return n
}
/sha512/sha512_test.go
0,0 → 1,125
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// SHA512 hash algorithm. See FIPS 180-2.
 
package sha512
 
import (
"fmt"
"io"
"testing"
)
 
type sha512Test struct {
out string
in string
}
 
var golden = []sha512Test{
{"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", ""},
{"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", "a"},
{"2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d", "ab"},
{"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "abc"},
{"d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f", "abcd"},
{"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1", "abcde"},
{"e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7", "abcdef"},
{"d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c", "abcdefg"},
{"a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce", "abcdefgh"},
{"f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe", "abcdefghi"},
{"ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745", "abcdefghij"},
{"2210d99af9c8bdecda1b4beff822136753d8342505ddce37f1314e2cdbb488c6016bdaa9bd2ffa513dd5de2e4b50f031393d8ab61f773b0e0130d7381e0f8a1d", "Discard medicine more than two years old."},
{"a687a8985b4d8d0a24f115fe272255c6afaf3909225838546159c1ed685c211a203796ae8ecc4c81a5b6315919b3a64f10713da07e341fcdbb08541bf03066ce", "He who has a shady past knows that nice guys finish last."},
{"8ddb0392e818b7d585ab22769a50df660d9f6d559cca3afc5691b8ca91b8451374e42bcdabd64589ed7c91d85f626596228a5c8572677eb98bc6b624befb7af8", "I wouldn't marry him with a ten foot pole."},
{"26ed8f6ca7f8d44b6a8a54ae39640fa8ad5c673f70ee9ce074ba4ef0d483eea00bab2f61d8695d6b34df9c6c48ae36246362200ed820448bdc03a720366a87c6", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
{"e5a14bf044be69615aade89afcf1ab0389d5fc302a884d403579d1386a2400c089b0dbb387ed0f463f9ee342f8244d5a38cfbc0e819da9529fbff78368c9a982", "The days of the digital watch are numbered. -Tom Stoppard"},
{"420a1faa48919e14651bed45725abe0f7a58e0f099424c4e5a49194946e38b46c1f8034b18ef169b2e31050d1648e0b982386595f7df47da4b6fd18e55333015", "Nepal premier won't resign."},
{"d926a863beadb20134db07683535c72007b0e695045876254f341ddcccde132a908c5af57baa6a6a9c63e6649bba0c213dc05fadcf9abccea09f23dcfb637fbe", "For every action there is an equal and opposite government program."},
{"9a98dd9bb67d0da7bf83da5313dff4fd60a4bac0094f1b05633690ffa7f6d61de9a1d4f8617937d560833a9aaa9ccafe3fd24db418d0e728833545cadd3ad92d", "His money is twice tainted: 'taint yours and 'taint mine."},
{"d7fde2d2351efade52f4211d3746a0780a26eec3df9b2ed575368a8a1c09ec452402293a8ea4eceb5a4f60064ea29b13cdd86918cd7a4faf366160b009804107", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
{"b0f35ffa2697359c33a56f5c0cf715c7aeed96da9905ca2698acadb08fbc9e669bf566b6bd5d61a3e86dc22999bcc9f2224e33d1d4f32a228cf9d0349e2db518", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
{"3d2e5f91778c9e66f7e061293aaa8a8fc742dd3b2e4f483772464b1144189b49273e610e5cccd7a81a19ca1fa70f16b10f1a100a4d8c1372336be8484c64b311", "size: a.out: bad magic"},
{"b2f68ff58ac015efb1c94c908b0d8c2bf06f491e4de8e6302c49016f7f8a33eac3e959856c7fddbc464de618701338a4b46f76dbfaf9a1e5262b5f40639771c7", "The major problem is with sendmail. -Mark Horton"},
{"d8c92db5fdf52cf8215e4df3b4909d29203ff4d00e9ad0b64a6a4e04dec5e74f62e7c35c7fb881bd5de95442123df8f57a489b0ae616bd326f84d10021121c57", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
{"19a9f8dc0a233e464e8566ad3ca9b91e459a7b8c4780985b015776e1bf239a19bc233d0556343e2b0a9bc220900b4ebf4f8bdf89ff8efeaf79602d6849e6f72e", "If the enemy is within range, then so are you."},
{"00b4c41f307bde87301cdc5b5ab1ae9a592e8ecbb2021dd7bc4b34e2ace60741cc362560bec566ba35178595a91932b8d5357e2c9cec92d393b0fa7831852476", "It's well we cannot hear the screams/That we create in others' dreams."},
{"91eccc3d5375fd026e4d6787874b1dce201cecd8a27dbded5065728cb2d09c58a3d467bb1faf353bf7ba567e005245d5321b55bc344f7c07b91cb6f26c959be7", "You remind me of a TV show, but that's all right: I watch it anyway."},
{"fabbbe22180f1f137cfdc9556d2570e775d1ae02a597ded43a72a40f9b485d500043b7be128fb9fcd982b83159a0d99aa855a9e7cc4240c00dc01a9bdf8218d7", "C is as portable as Stonehedge!!"},
{"2ecdec235c1fa4fc2a154d8fba1dddb8a72a1ad73838b51d792331d143f8b96a9f6fcb0f34d7caa351fe6d88771c4f105040e0392f06e0621689d33b2f3ba92e", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
{"7ad681f6f96f82f7abfa7ecc0334e8fa16d3dc1cdc45b60b7af43fe4075d2357c0c1d60e98350f1afb1f2fe7a4d7cd2ad55b88e458e06b73c40b437331f5dab4", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
{"833f9248ab4a3b9e5131f745fda1ffd2dd435b30e965957e78291c7ab73605fd1912b0794e5c233ab0a12d205a39778d19b83515d6a47003f19cdee51d98c7e0", "How can you write a big system without C++? -Paul Glick"},
}
 
var golden384 = []sha512Test{
{"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", ""},
{"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", "a"},
{"c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd", "ab"},
{"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", "abc"},
{"1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b", "abcd"},
{"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0", "abcde"},
{"c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5", "abcdef"},
{"9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22", "abcdefg"},
{"9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806", "abcdefgh"},
{"ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df", "abcdefghi"},
{"a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c", "abcdefghij"},
{"86f58ec2d74d1b7f8eb0c2ff0967316699639e8d4eb129de54bdf34c96cdbabe200d052149f2dd787f43571ba74670d4", "Discard medicine more than two years old."},
{"ae4a2b639ca9bfa04b1855d5a05fe7f230994f790891c6979103e2605f660c4c1262a48142dcbeb57a1914ba5f7c3fa7", "He who has a shady past knows that nice guys finish last."},
{"40ae213df6436eca952aa6841886fcdb82908ef1576a99c8f49bb9dd5023169f7c53035abdda0b54c302f4974e2105e7", "I wouldn't marry him with a ten foot pole."},
{"e7cf8b873c9bc950f06259aa54309f349cefa72c00d597aebf903e6519a50011dfe355afff064a10701c705693848df9", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
{"c3d4f0f4047181c7d39d34703365f7bf70207183caf2c2f6145f04da895ef69124d9cdeb635da636c3a474e61024e29b", "The days of the digital watch are numbered. -Tom Stoppard"},
{"a097aab567e167d5cf93676ed73252a69f9687cb3179bb2d27c9878119e94bf7b7c4b58dc90582edfaf66e11388ed714", "Nepal premier won't resign."},
{"5026ca45c41fc64712eb65065da92f6467541c78f8966d3fe2c8e3fb769a3ec14215f819654b47bd64f7f0eac17184f3", "For every action there is an equal and opposite government program."},
{"ac1cc0f5ac8d5f5514a7b738ac322b7fb52a161b449c3672e9b6a6ad1a5e4b26b001cf3bad24c56598676ca17d4b445a", "His money is twice tainted: 'taint yours and 'taint mine."},
{"722d10c5de371ec0c8c4b5247ac8a5f1d240d68c73f8da13d8b25f0166d6f309bf9561979a111a0049405771d201941a", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
{"dc2d3ea18bfa10549c63bf2b75b39b5167a80c12aff0e05443168ea87ff149fb0eda5e0bd234eb5d48c7d02ffc5807f1", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
{"1d67c969e2a945ae5346d2139760261504d4ba164c522443afe19ef3e29b152a4c52445489cfc9d7215e5a450e8e1e4e", "size: a.out: bad magic"},
{"5ff8e075e465646e7b73ef36d812c6e9f7d60fa6ea0e533e5569b4f73cde53cdd2cc787f33540af57cca3fe467d32fe0", "The major problem is with sendmail. -Mark Horton"},
{"5bd0a997a67c9ae1979a894eb0cde403dde003c9b6f2c03cf21925c42ff4e1176e6df1ca005381612ef18457b9b7ec3b", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
{"1eee6da33e7e54fc5be52ae23b94b16ba4d2a947ae4505c6a3edfc7401151ea5205ac01b669b56f27d8ef7f175ed7762", "If the enemy is within range, then so are you."},
{"76b06e9dea66bfbb1a96029426dc0dfd7830bd297eb447ff5358d94a87cd00c88b59df2493fef56ecbb5231073892ea9", "It's well we cannot hear the screams/That we create in others' dreams."},
{"12acaf21452cff586143e3f5db0bfdf7802c057e1adf2a619031c4e1b0ccc4208cf6cef8fe722bbaa2fb46a30d9135d8", "You remind me of a TV show, but that's all right: I watch it anyway."},
{"0fc23d7f4183efd186f0bc4fc5db867e026e2146b06cb3d52f4bdbd57d1740122caa853b41868b197b2ac759db39df88", "C is as portable as Stonehedge!!"},
{"bc805578a7f85d34a86a32976e1c34fe65cf815186fbef76f46ef99cda10723f971f3f1464d488243f5e29db7488598d", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
{"b23918399a12ebf4431559eec3813eaf7412e875fd7464f16d581e473330842d2e96c6be49a7ce3f9bb0b8bc0fcbe0fe", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
{"1764b700eb1ead52a2fc33cc28975c2180f1b8faa5038d94cffa8d78154aab16e91dd787e7b0303948ebed62561542c8", "How can you write a big system without C++? -Paul Glick"},
}
 
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("sha512[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
for i := 0; i < len(golden384); i++ {
g := golden384[i]
c := New384()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("sha384[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
}
/sha512/sha512.go
0,0 → 1,177
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package sha512 implements the SHA384 and SHA512 hash algorithms as defined
// in FIPS 180-2.
package sha512
 
import (
"crypto"
"hash"
)
 
func init() {
crypto.RegisterHash(crypto.SHA384, New384)
crypto.RegisterHash(crypto.SHA512, New)
}
 
// The size of a SHA512 checksum in bytes.
const Size = 64
 
// The size of a SHA384 checksum in bytes.
const Size384 = 48
 
// The blocksize of SHA512 and SHA384 in bytes.
const BlockSize = 128
 
const (
_Chunk = 128
_Init0 = 0x6a09e667f3bcc908
_Init1 = 0xbb67ae8584caa73b
_Init2 = 0x3c6ef372fe94f82b
_Init3 = 0xa54ff53a5f1d36f1
_Init4 = 0x510e527fade682d1
_Init5 = 0x9b05688c2b3e6c1f
_Init6 = 0x1f83d9abfb41bd6b
_Init7 = 0x5be0cd19137e2179
_Init0_384 = 0xcbbb9d5dc1059ed8
_Init1_384 = 0x629a292a367cd507
_Init2_384 = 0x9159015a3070dd17
_Init3_384 = 0x152fecd8f70e5939
_Init4_384 = 0x67332667ffc00b31
_Init5_384 = 0x8eb44a8768581511
_Init6_384 = 0xdb0c2e0d64f98fa7
_Init7_384 = 0x47b5481dbefa4fa4
)
 
// digest represents the partial evaluation of a checksum.
type digest struct {
h [8]uint64
x [_Chunk]byte
nx int
len uint64
is384 bool // mark if this digest is SHA-384
}
 
func (d *digest) Reset() {
if !d.is384 {
d.h[0] = _Init0
d.h[1] = _Init1
d.h[2] = _Init2
d.h[3] = _Init3
d.h[4] = _Init4
d.h[5] = _Init5
d.h[6] = _Init6
d.h[7] = _Init7
} else {
d.h[0] = _Init0_384
d.h[1] = _Init1_384
d.h[2] = _Init2_384
d.h[3] = _Init3_384
d.h[4] = _Init4_384
d.h[5] = _Init5_384
d.h[6] = _Init6_384
d.h[7] = _Init7_384
}
d.nx = 0
d.len = 0
}
 
// New returns a new hash.Hash computing the SHA512 checksum.
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
 
// New384 returns a new hash.Hash computing the SHA384 checksum.
func New384() hash.Hash {
d := new(digest)
d.is384 = true
d.Reset()
return d
}
 
func (d *digest) Size() int {
if !d.is384 {
return Size
}
return Size384
}
 
func (d *digest) BlockSize() int { return BlockSize }
 
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.len += uint64(nn)
if d.nx > 0 {
n := len(p)
if n > _Chunk-d.nx {
n = _Chunk - d.nx
}
for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i]
}
d.nx += n
if d.nx == _Chunk {
_Block(d, d.x[0:])
d.nx = 0
}
p = p[n:]
}
n := _Block(d, p)
p = p[n:]
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
 
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := new(digest)
*d = *d0
 
// Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
len := d.len
var tmp [128]byte
tmp[0] = 0x80
if len%128 < 112 {
d.Write(tmp[0 : 112-len%128])
} else {
d.Write(tmp[0 : 128+112-len%128])
}
 
// Length in bits.
len <<= 3
for i := uint(0); i < 16; i++ {
tmp[i] = byte(len >> (120 - 8*i))
}
d.Write(tmp[0:16])
 
if d.nx != 0 {
panic("d.nx != 0")
}
 
h := d.h[:]
size := Size
if d.is384 {
h = d.h[:6]
size = Size384
}
 
var digest [Size]byte
for i, s := range h {
digest[i*8] = byte(s >> 56)
digest[i*8+1] = byte(s >> 48)
digest[i*8+2] = byte(s >> 40)
digest[i*8+3] = byte(s >> 32)
digest[i*8+4] = byte(s >> 24)
digest[i*8+5] = byte(s >> 16)
digest[i*8+6] = byte(s >> 8)
digest[i*8+7] = byte(s)
}
 
return append(in, digest[:size]...)
}
/x509/pkcs1.go
0,0 → 1,122
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"crypto/rsa"
"encoding/asn1"
"errors"
"math/big"
)
 
// 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
// We ignore these values, if present, because rsa will calculate them.
Dp *big.Int `asn1:"optional"`
Dq *big.Int `asn1:"optional"`
Qinv *big.Int `asn1:"optional"`
 
AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional"`
}
 
type pkcs1AdditionalRSAPrime struct {
Prime *big.Int
 
// We ignore these values because rsa will calculate them.
Exp *big.Int
Coeff *big.Int
}
 
// ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) {
var priv pkcs1PrivateKey
rest, err := asn1.Unmarshal(der, &priv)
if len(rest) > 0 {
err = asn1.SyntaxError{Msg: "trailing data"}
return
}
if err != nil {
return
}
 
if priv.Version > 1 {
return nil, errors.New("x509: unsupported private key version")
}
 
if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
return nil, errors.New("private key contains zero or negative value")
}
 
key = new(rsa.PrivateKey)
key.PublicKey = rsa.PublicKey{
E: priv.E,
N: priv.N,
}
 
key.D = priv.D
key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
key.Primes[0] = priv.P
key.Primes[1] = priv.Q
for i, a := range priv.AdditionalPrimes {
if a.Prime.Sign() <= 0 {
return nil, errors.New("private key contains zero or negative prime")
}
key.Primes[i+2] = a.Prime
// We ignore the other two values because rsa will calculate
// them as needed.
}
 
err = key.Validate()
if err != nil {
return nil, err
}
key.Precompute()
 
return
}
 
// MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
key.Precompute()
 
version := 0
if len(key.Primes) > 2 {
version = 1
}
 
priv := pkcs1PrivateKey{
Version: version,
N: key.N,
E: key.PublicKey.E,
D: key.D,
P: key.Primes[0],
Q: key.Primes[1],
Dp: key.Precomputed.Dp,
Dq: key.Precomputed.Dq,
Qinv: key.Precomputed.Qinv,
}
 
priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
for i, values := range key.Precomputed.CRTValues {
priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
priv.AdditionalPrimes[i].Exp = values.Exp
priv.AdditionalPrimes[i].Coeff = values.Coeff
}
 
b, _ := asn1.Marshal(priv)
return b
}
 
// rsaPublicKey reflects the ASN.1 structure of a PKCS#1 public key.
type rsaPublicKey struct {
N *big.Int
E int
}
/x509/verify_test.go
0,0 → 1,420
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"crypto/x509/pkix"
"encoding/pem"
"errors"
"strings"
"testing"
"time"
)
 
type verifyTest struct {
leaf string
intermediates []string
roots []string
currentTime int64
dnsName string
nilRoots bool
 
errorCallback func(*testing.T, int, error) bool
expectedChains [][]string
}
 
var verifyTests = []verifyTest{
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1302726541,
dnsName: "www.google.com",
 
expectedChains: [][]string{
{"Google", "Thawte", "VeriSign"},
},
},
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1302726541,
dnsName: "WwW.GooGLE.coM",
 
expectedChains: [][]string{
{"Google", "Thawte", "VeriSign"},
},
},
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1302726541,
dnsName: "www.example.com",
 
errorCallback: expectHostnameError,
},
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
nilRoots: true, // verifies that we don't crash
currentTime: 1302726541,
dnsName: "www.google.com",
errorCallback: expectAuthorityUnknown,
},
{
leaf: googleLeaf,
intermediates: []string{thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1,
dnsName: "www.example.com",
 
errorCallback: expectExpired,
},
{
leaf: googleLeaf,
roots: []string{verisignRoot},
currentTime: 1302726541,
dnsName: "www.google.com",
 
errorCallback: expectAuthorityUnknown,
},
{
leaf: googleLeaf,
intermediates: []string{verisignRoot, thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1302726541,
dnsName: "www.google.com",
 
expectedChains: [][]string{
{"Google", "Thawte", "VeriSign"},
},
},
{
leaf: dnssecExpLeaf,
intermediates: []string{startComIntermediate},
roots: []string{startComRoot},
currentTime: 1302726541,
 
expectedChains: [][]string{
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
},
},
{
leaf: dnssecExpLeaf,
intermediates: []string{startComIntermediate, startComRoot},
roots: []string{startComRoot},
currentTime: 1302726541,
 
expectedChains: [][]string{
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority", "StartCom Certification Authority"},
},
},
}
 
func expectHostnameError(t *testing.T, i int, err error) (ok bool) {
if _, ok := err.(HostnameError); !ok {
t.Errorf("#%d: error was not a HostnameError: %s", i, err)
return false
}
return true
}
 
func expectExpired(t *testing.T, i int, err error) (ok bool) {
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != Expired {
t.Errorf("#%d: error was not Expired: %s", i, err)
return false
}
return true
}
 
func expectAuthorityUnknown(t *testing.T, i int, err error) (ok bool) {
if _, ok := err.(UnknownAuthorityError); !ok {
t.Errorf("#%d: error was not UnknownAuthorityError: %s", i, err)
return false
}
return true
}
 
func certificateFromPEM(pemBytes string) (*Certificate, error) {
block, _ := pem.Decode([]byte(pemBytes))
if block == nil {
return nil, errors.New("failed to decode PEM")
}
return ParseCertificate(block.Bytes)
}
 
func TestVerify(t *testing.T) {
for i, test := range verifyTests {
opts := VerifyOptions{
Roots: NewCertPool(),
Intermediates: NewCertPool(),
DNSName: test.dnsName,
CurrentTime: time.Unix(test.currentTime, 0),
}
if test.nilRoots {
opts.Roots = nil
}
 
for j, root := range test.roots {
ok := opts.Roots.AppendCertsFromPEM([]byte(root))
if !ok {
t.Errorf("#%d: failed to parse root #%d", i, j)
return
}
}
 
for j, intermediate := range test.intermediates {
ok := opts.Intermediates.AppendCertsFromPEM([]byte(intermediate))
if !ok {
t.Errorf("#%d: failed to parse intermediate #%d", i, j)
return
}
}
 
leaf, err := certificateFromPEM(test.leaf)
if err != nil {
t.Errorf("#%d: failed to parse leaf: %s", i, err)
return
}
 
chains, err := leaf.Verify(opts)
 
if test.errorCallback == nil && err != nil {
t.Errorf("#%d: unexpected error: %s", i, err)
}
if test.errorCallback != nil {
if !test.errorCallback(t, i, err) {
return
}
}
 
if len(chains) != len(test.expectedChains) {
t.Errorf("#%d: wanted %d chains, got %d", i, len(test.expectedChains), len(chains))
}
 
// We check that each returned chain matches a chain from
// expectedChains but an entry in expectedChains can't match
// two chains.
seenChains := make([]bool, len(chains))
NextOutputChain:
for _, chain := range chains {
TryNextExpected:
for j, expectedChain := range test.expectedChains {
if seenChains[j] {
continue
}
if len(chain) != len(expectedChain) {
continue
}
for k, cert := range chain {
if strings.Index(nameToKey(&cert.Subject), expectedChain[k]) == -1 {
continue TryNextExpected
}
}
// we matched
seenChains[j] = true
continue NextOutputChain
}
t.Errorf("#%d: No expected chain matched %s", i, chainToDebugString(chain))
}
}
}
 
func chainToDebugString(chain []*Certificate) string {
var chainStr string
for _, cert := range chain {
if len(chainStr) > 0 {
chainStr += " -> "
}
chainStr += nameToKey(&cert.Subject)
}
return chainStr
}
 
func nameToKey(name *pkix.Name) string {
return strings.Join(name.Country, ",") + "/" + strings.Join(name.Organization, ",") + "/" + strings.Join(name.OrganizationalUnit, ",") + "/" + name.CommonName
}
 
const verisignRoot = `-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
-----END CERTIFICATE-----
`
 
const thawteIntermediate = `-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
-----END CERTIFICATE-----
`
 
const googleLeaf = `-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x
MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN
gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L
05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5
u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6
z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==
-----END CERTIFICATE-----`
 
const dnssecExpLeaf = `-----BEGIN CERTIFICATE-----
MIIGzTCCBbWgAwIBAgIDAdD6MA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTAwNzA0MTQ1MjQ1
WhcNMTEwNzA1MTA1NzA0WjCBwTEgMB4GA1UEDRMXMjIxMTM3LWxpOWE5dHhJRzZM
NnNyVFMxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVQZXJzb25hIE5vdCBWYWxpZGF0
ZWQxKTAnBgNVBAsTIFN0YXJ0Q29tIEZyZWUgQ2VydGlmaWNhdGUgTWVtYmVyMRsw
GQYDVQQDExJ3d3cuZG5zc2VjLWV4cC5vcmcxKDAmBgkqhkiG9w0BCQEWGWhvc3Rt
YXN0ZXJAZG5zc2VjLWV4cC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDEdF/22vaxrPbqpgVYMWi+alfpzBctpbfLBdPGuqOazJdCT0NbWcK8/+B4
X6OlSOURNIlwLzhkmwVsWdVv6dVSaN7d4yI/fJkvgfDB9+au+iBJb6Pcz8ULBfe6
D8HVvqKdORp6INzHz71z0sghxrQ0EAEkoWAZLh+kcn2ZHdcmZaBNUfjmGbyU6PRt
RjdqoP+owIaC1aktBN7zl4uO7cRjlYFdusINrh2kPP02KAx2W84xjxX1uyj6oS6e
7eBfvcwe8czW/N1rbE0CoR7h9+HnIrjnVG9RhBiZEiw3mUmF++Up26+4KTdRKbu3
+BL4yMpfd66z0+zzqu+HkvyLpFn5AgMBAAGjggL/MIIC+zAJBgNVHRMEAjAAMAsG
A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUy04I5guM
drzfh2JQaXhgV86+4jUwHwYDVR0jBBgwFoAU60I00Jiwq5/0G2sI98xkLu8OLEUw
LQYDVR0RBCYwJIISd3d3LmRuc3NlYy1leHAub3Jngg5kbnNzZWMtZXhwLm9yZzCC
AUIGA1UdIASCATkwggE1MIIBMQYLKwYBBAGBtTcBAgIwggEgMC4GCCsGAQUFBwIB
FiJodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kucGRmMDQGCCsGAQUFBwIB
FihodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9pbnRlcm1lZGlhdGUucGRmMIG3Bggr
BgEFBQcCAjCBqjAUFg1TdGFydENvbSBMdGQuMAMCAQEagZFMaW1pdGVkIExpYWJp
bGl0eSwgc2VlIHNlY3Rpb24gKkxlZ2FsIExpbWl0YXRpb25zKiBvZiB0aGUgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUG9saWN5IGF2YWlsYWJsZSBh
dCBodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kucGRmMGEGA1UdHwRaMFgw
KqAooCaGJGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2NydDEtY3JsLmNybDAqoCig
JoYkaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0MS1jcmwuY3JsMIGOBggrBgEF
BQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2NzcC5zdGFydHNzbC5jb20v
c3ViL2NsYXNzMS9zZXJ2ZXIvY2EwQgYIKwYBBQUHMAKGNmh0dHA6Ly93d3cuc3Rh
cnRzc2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuc2VydmVyLmNhLmNydDAjBgNVHRIE
HDAahhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJKoZIhvcNAQEFBQADggEB
ACXj6SB59KRJPenn6gUdGEqcta97U769SATyiQ87i9er64qLwvIGLMa3o2Rcgl2Y
kghUeyLdN/EXyFBYA8L8uvZREPoc7EZukpT/ZDLXy9i2S0jkOxvF2fD/XLbcjGjM
iEYG1/6ASw0ri9C0k4oDDoJLCoeH9++yqF7SFCCMcDkJqiAGXNb4euDpa8vCCtEQ
CSS+ObZbfkreRt3cNCf5LfCXe9OsTnCfc8Cuq81c0oLaG+SmaLUQNBuToq8e9/Zm
+b+/a3RVjxmkV5OCcGVBxsXNDn54Q6wsdw0TBMcjwoEndzpLS7yWgFbbkq5ZiGpw
Qibb2+CfKuQ+WFV1GkVQmVA=
-----END CERTIFICATE-----`
 
const startComIntermediate = `-----BEGIN CERTIFICATE-----
MIIGNDCCBBygAwIBAgIBGDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcxMDI0MjA1NDE3WjCB
jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj0PREGBiE
gFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJA
pgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVv
kvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/
ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5
xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwID
AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
VR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAIQlJPqWIbuALi0jaMU2P91ZXouHTYlfp
tVbzhUV1O+VQHwSL5qBaPucAroXQ+/8gA2TLrQLhxpFy+KNN1t7ozD+hiqLjfDen
xk+PNdb01m4Ge90h2c9W/8swIkn+iQTzheWq8ecf6HWQTd35RvdCNPdFWAwRDYSw
xtpdPvkBnufh2lWVvnQce/xNFE+sflVHfXv0pQ1JHpXo9xLBzP92piVH0PN1Nb6X
t1gW66pceG/sUzCv6gRNzKkC4/C2BBL2MLERPZBOVmTX3DxDX3M570uvh+v2/miI
RHLq0gfGabDBoYvvF0nXYbFFSF87ICHpW7LM9NfpMfULFWE7epTj69m8f5SuauNi
YpaoZHy4h/OZMn6SolK+u/hlz8nyMPyLwcKmltdfieFcNID1j0cHL7SRv7Gifl9L
WtBbnySGBVFaaQNlQ0lxxeBvlDRr9hvYqbBMflPrj0jfyjO1SPo2ShpTpjMM0InN
SRXNiTE8kMBy12VLUjWKRhFEuT2OKGWmPnmeXAhEKa2wNREuIU640ucQPl2Eg7PD
wuTSxv0JS3QJ3fGz0xk+gA2iCxnwOOfFwq/iI9th4p1cbiCJSS4jarJiwUW0n6+L
p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un
0q6Dp6jOW6c=
-----END CERTIFICATE-----`
 
const startComRoot = `-----BEGIN CERTIFICATE-----
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
-----END CERTIFICATE-----`
/x509/verify.go
0,0 → 1,278
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"strings"
"time"
"unicode/utf8"
)
 
type InvalidReason int
 
const (
// NotAuthorizedToSign results when a certificate is signed by another
// which isn't marked as a CA certificate.
NotAuthorizedToSign InvalidReason = iota
// Expired results when a certificate has expired, based on the time
// given in the VerifyOptions.
Expired
// CANotAuthorizedForThisName results when an intermediate or root
// certificate has a name constraint which doesn't include the name
// being checked.
CANotAuthorizedForThisName
)
 
// CertificateInvalidError results when an odd error occurs. Users of this
// library probably want to handle all these errors uniformly.
type CertificateInvalidError struct {
Cert *Certificate
Reason InvalidReason
}
 
func (e CertificateInvalidError) Error() string {
switch e.Reason {
case NotAuthorizedToSign:
return "x509: certificate is not authorized to sign other other certificates"
case Expired:
return "x509: certificate has expired or is not yet valid"
case CANotAuthorizedForThisName:
return "x509: a root or intermediate certificate is not authorized to sign in this domain"
}
return "x509: unknown error"
}
 
// HostnameError results when the set of authorized names doesn't match the
// requested name.
type HostnameError struct {
Certificate *Certificate
Host string
}
 
func (h HostnameError) Error() string {
var valid string
c := h.Certificate
if len(c.DNSNames) > 0 {
valid = strings.Join(c.DNSNames, ", ")
} else {
valid = c.Subject.CommonName
}
return "certificate is valid for " + valid + ", not " + h.Host
}
 
// UnknownAuthorityError results when the certificate issuer is unknown
type UnknownAuthorityError struct {
cert *Certificate
}
 
func (e UnknownAuthorityError) Error() string {
return "x509: certificate signed by unknown authority"
}
 
// VerifyOptions contains parameters for Certificate.Verify. It's a structure
// because other PKIX verification APIs have ended up needing many options.
type VerifyOptions struct {
DNSName string
Intermediates *CertPool
Roots *CertPool
CurrentTime time.Time // if zero, the current time is used
}
 
const (
leafCertificate = iota
intermediateCertificate
rootCertificate
)
 
// isValid performs validity checks on the c.
func (c *Certificate) isValid(certType int, opts *VerifyOptions) error {
now := opts.CurrentTime
if now.IsZero() {
now = time.Now()
}
if now.Before(c.NotBefore) || now.After(c.NotAfter) {
return CertificateInvalidError{c, Expired}
}
 
if len(c.PermittedDNSDomains) > 0 {
for _, domain := range c.PermittedDNSDomains {
if opts.DNSName == domain ||
(strings.HasSuffix(opts.DNSName, domain) &&
len(opts.DNSName) >= 1+len(domain) &&
opts.DNSName[len(opts.DNSName)-len(domain)-1] == '.') {
continue
}
 
return CertificateInvalidError{c, CANotAuthorizedForThisName}
}
}
 
// KeyUsage status flags are ignored. From Engineering Security, Peter
// Gutmann: A European government CA marked its signing certificates as
// being valid for encryption only, but no-one noticed. Another
// European CA marked its signature keys as not being valid for
// signatures. A different CA marked its own trusted root certificate
// as being invalid for certificate signing. Another national CA
// distributed a certificate to be used to encrypt data for the
// country’s tax authority that was marked as only being usable for
// digital signatures but not for encryption. Yet another CA reversed
// the order of the bit flags in the keyUsage due to confusion over
// encoding endianness, essentially setting a random keyUsage in
// certificates that it issued. Another CA created a self-invalidating
// certificate by adding a certificate policy statement stipulating
// that the certificate had to be used strictly as specified in the
// keyUsage, and a keyUsage containing a flag indicating that the RSA
// encryption key could only be used for Diffie-Hellman key agreement.
 
if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
return CertificateInvalidError{c, NotAuthorizedToSign}
}
 
return nil
}
 
// Verify attempts to verify c by building one or more chains from c to a
// certificate in opts.roots, using certificates in opts.Intermediates if
// needed. If successful, it returns one or chains where the first element of
// the chain is c and the last element is from opts.Roots.
//
// WARNING: this doesn't do any revocation checking.
func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
err = c.isValid(leafCertificate, &opts)
if err != nil {
return
}
if len(opts.DNSName) > 0 {
err = c.VerifyHostname(opts.DNSName)
if err != nil {
return
}
}
return c.buildChains(make(map[int][][]*Certificate), []*Certificate{c}, &opts)
}
 
func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
n := make([]*Certificate, len(chain)+1)
copy(n, chain)
n[len(chain)] = cert
return n
}
 
func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) {
for _, rootNum := range opts.Roots.findVerifiedParents(c) {
root := opts.Roots.certs[rootNum]
err = root.isValid(rootCertificate, opts)
if err != nil {
continue
}
chains = append(chains, appendToFreshChain(currentChain, root))
}
 
nextIntermediate:
for _, intermediateNum := range opts.Intermediates.findVerifiedParents(c) {
intermediate := opts.Intermediates.certs[intermediateNum]
for _, cert := range currentChain {
if cert == intermediate {
continue nextIntermediate
}
}
err = intermediate.isValid(intermediateCertificate, opts)
if err != nil {
continue
}
var childChains [][]*Certificate
childChains, ok := cache[intermediateNum]
if !ok {
childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts)
cache[intermediateNum] = childChains
}
chains = append(chains, childChains...)
}
 
if len(chains) > 0 {
err = nil
}
 
if len(chains) == 0 && err == nil {
err = UnknownAuthorityError{c}
}
 
return
}
 
func matchHostnames(pattern, host string) bool {
if len(pattern) == 0 || len(host) == 0 {
return false
}
 
patternParts := strings.Split(pattern, ".")
hostParts := strings.Split(host, ".")
 
if len(patternParts) != len(hostParts) {
return false
}
 
for i, patternPart := range patternParts {
if patternPart == "*" {
continue
}
if patternPart != hostParts[i] {
return false
}
}
 
return true
}
 
// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
// an explicitly ASCII function to avoid any sharp corners resulting from
// performing Unicode operations on DNS labels.
func toLowerCaseASCII(in string) string {
// If the string is already lower-case then there's nothing to do.
isAlreadyLowerCase := true
for _, c := range in {
if c == utf8.RuneError {
// If we get a UTF-8 error then there might be
// upper-case ASCII bytes in the invalid sequence.
isAlreadyLowerCase = false
break
}
if 'A' <= c && c <= 'Z' {
isAlreadyLowerCase = false
break
}
}
 
if isAlreadyLowerCase {
return in
}
 
out := []byte(in)
for i, c := range out {
if 'A' <= c && c <= 'Z' {
out[i] += 'a' - 'A'
}
}
return string(out)
}
 
// VerifyHostname returns nil if c is a valid certificate for the named host.
// Otherwise it returns an error describing the mismatch.
func (c *Certificate) VerifyHostname(h string) error {
lowered := toLowerCaseASCII(h)
 
if len(c.DNSNames) > 0 {
for _, match := range c.DNSNames {
if matchHostnames(toLowerCaseASCII(match), lowered) {
return nil
}
}
// If Subject Alt Name is given, we ignore the common name.
} else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
return nil
}
 
return HostnameError{c, h}
}
/x509/x509_test.go
0,0 → 1,475
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"bytes"
"crypto/dsa"
"crypto/rand"
"crypto/rsa"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"math/big"
"testing"
"time"
)
 
func TestParsePKCS1PrivateKey(t *testing.T) {
block, _ := pem.Decode([]byte(pemPrivateKey))
priv, err := ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
t.Errorf("Failed to parse private key: %s", err)
return
}
if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 ||
priv.PublicKey.E != rsaPrivateKey.PublicKey.E ||
priv.D.Cmp(rsaPrivateKey.D) != 0 ||
priv.Primes[0].Cmp(rsaPrivateKey.Primes[0]) != 0 ||
priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 {
t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey)
}
}
 
func TestParsePKIXPublicKey(t *testing.T) {
block, _ := pem.Decode([]byte(pemPublicKey))
pub, err := ParsePKIXPublicKey(block.Bytes)
if err != nil {
t.Errorf("Failed to parse RSA public key: %s", err)
return
}
rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
t.Errorf("Value returned from ParsePKIXPublicKey was not an RSA public key")
return
}
 
pubBytes2, err := MarshalPKIXPublicKey(rsaPub)
if err != nil {
t.Errorf("Failed to marshal RSA public key for the second time: %s", err)
return
}
if !bytes.Equal(pubBytes2, block.Bytes) {
t.Errorf("Reserialization of public key didn't match. got %x, want %x", pubBytes2, block.Bytes)
}
}
 
var pemPublicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+
wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k
enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ
FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg
fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR
FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ
+QIDAQAB
-----END PUBLIC KEY-----
`
 
var pemPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
-----END RSA PRIVATE KEY-----
`
 
func bigFromString(s string) *big.Int {
ret := new(big.Int)
ret.SetString(s, 10)
return ret
}
 
func fromBase10(base10 string) *big.Int {
i := new(big.Int)
i.SetString(base10, 10)
return i
}
 
func bigFromHexString(s string) *big.Int {
ret := new(big.Int)
ret.SetString(s, 16)
return ret
}
 
var rsaPrivateKey = &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: bigFromString("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"),
E: 65537,
},
D: bigFromString("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"),
Primes: []*big.Int{
bigFromString("98920366548084643601728869055592650835572950932266967461790948584315647051443"),
bigFromString("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
},
}
 
func TestMarshalRSAPrivateKey(t *testing.T) {
priv := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
E: 3,
},
D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"),
Primes: []*big.Int{
fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
},
}
 
derBytes := MarshalPKCS1PrivateKey(priv)
 
priv2, err := ParsePKCS1PrivateKey(derBytes)
if err != nil {
t.Errorf("error parsing serialized key: %s", err)
return
}
if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 ||
priv.PublicKey.E != priv2.PublicKey.E ||
priv.D.Cmp(priv2.D) != 0 ||
len(priv2.Primes) != 3 ||
priv.Primes[0].Cmp(priv2.Primes[0]) != 0 ||
priv.Primes[1].Cmp(priv2.Primes[1]) != 0 ||
priv.Primes[2].Cmp(priv2.Primes[2]) != 0 {
t.Errorf("got:%+v want:%+v", priv, priv2)
}
}
 
type matchHostnamesTest struct {
pattern, host string
ok bool
}
 
var matchHostnamesTests = []matchHostnamesTest{
{"a.b.c", "a.b.c", true},
{"a.b.c", "b.b.c", false},
{"", "b.b.c", false},
{"a.b.c", "", false},
{"example.com", "example.com", true},
{"example.com", "www.example.com", false},
{"*.example.com", "www.example.com", true},
{"*.example.com", "xyz.www.example.com", false},
{"*.*.example.com", "xyz.www.example.com", true},
{"*.www.*.com", "xyz.www.example.com", true},
}
 
func TestMatchHostnames(t *testing.T) {
for i, test := range matchHostnamesTests {
r := matchHostnames(test.pattern, test.host)
if r != test.ok {
t.Errorf("#%d mismatch got: %t want: %t", i, r, test.ok)
}
}
}
 
func TestCertificateParse(t *testing.T) {
s, _ := hex.DecodeString(certBytes)
certs, err := ParseCertificates(s)
if err != nil {
t.Error(err)
}
if len(certs) != 2 {
t.Errorf("Wrong number of certs: got %d want 2", len(certs))
return
}
 
err = certs[0].CheckSignatureFrom(certs[1])
if err != nil {
t.Error(err)
}
 
if err := certs[0].VerifyHostname("mail.google.com"); err != nil {
t.Error(err)
}
}
 
var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" +
"f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" +
"20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" +
"20534743204341301e170d3039303332353136343932395a170d3130303332353136343932395a" +
"3069310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630" +
"140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c6520" +
"496e63311830160603550403130f6d61696c2e676f6f676c652e636f6d30819f300d06092a8648" +
"86f70d010101050003818d0030818902818100c5d6f892fccaf5614b064149e80a2c9581a218ef" +
"41ec35bd7a58125ae76f9ea54ddc893abbeb029f6b73616bf0ffd868791fba7af9c4aebf3706ba" +
"3eeaeed27435b4ddcfb157c05f351d66aa87fee0de072d66d773affbd36ab78bef090e0cc861a9" +
"03ac90dd98b51c9c41566c017f0beec3bff391051ffba0f5cc6850ad2a590203010001a381e730" +
"81e430280603551d250421301f06082b0601050507030106082b06010505070302060960864801" +
"86f842040130360603551d1f042f302d302ba029a0278625687474703a2f2f63726c2e74686177" +
"74652e636f6d2f54686177746553474343412e63726c307206082b060105050701010466306430" +
"2206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d303e0608" +
"2b060105050730028632687474703a2f2f7777772e7468617774652e636f6d2f7265706f736974" +
"6f72792f5468617774655f5347435f43412e637274300c0603551d130101ff04023000300d0609" +
"2a864886f70d01010505000381810062f1f3050ebc105e497c7aedf87e24d2f4a986bb3b837bd1" +
"9b91ebcad98b065992f6bd2b49b7d6d3cb2e427a99d606c7b1d46352527fac39e6a8b6726de5bf" +
"70212a52cba07634a5e332011bd1868e78eb5e3c93cf03072276786f207494feaa0ed9d53b2110" +
"a76571f90209cdae884385c882587030ee15f33d761e2e45a6bc308203233082028ca003020102" +
"020430000002300d06092a864886f70d0101050500305f310b3009060355040613025553311730" +
"15060355040a130e566572695369676e2c20496e632e31373035060355040b132e436c61737320" +
"33205075626c6963205072696d6172792043657274696669636174696f6e20417574686f726974" +
"79301e170d3034303531333030303030305a170d3134303531323233353935395a304c310b3009" +
"060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e672028" +
"50747929204c74642e311630140603550403130d5468617774652053474320434130819f300d06" +
"092a864886f70d010101050003818d0030818902818100d4d367d08d157faecd31fe7d1d91a13f" +
"0b713cacccc864fb63fc324b0794bd6f80ba2fe10493c033fc093323e90b742b71c403c6d2cde2" +
"2ff50963cdff48a500bfe0e7f388b72d32de9836e60aad007bc4644a3b847503f270927d0e62f5" +
"21ab693684317590f8bfc76c881b06957cc9e5a8de75a12c7a68dfd5ca1c875860190203010001" +
"a381fe3081fb30120603551d130101ff040830060101ff020100300b0603551d0f040403020106" +
"301106096086480186f842010104040302010630280603551d110421301fa41d301b3119301706" +
"035504031310507269766174654c6162656c332d313530310603551d1f042a30283026a024a022" +
"8620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c303206082b" +
"0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468" +
"617774652e636f6d30340603551d25042d302b06082b0601050507030106082b06010505070302" +
"06096086480186f8420401060a6086480186f845010801300d06092a864886f70d010105050003" +
"81810055ac63eadea1ddd2905f9f0bce76be13518f93d9052bc81b774bad6950a1eededcfddb07" +
"e9e83994dcab72792f06bfab8170c4a8edea5334edef1e53d906c7562bd15cf4d18a8eb42bb137" +
"9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" +
"36dcd585d6ace53f546f961e05af"
 
func TestCreateSelfSignedCertificate(t *testing.T) {
random := rand.Reader
 
block, _ := pem.Decode([]byte(pemPrivateKey))
priv, err := ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
t.Errorf("Failed to parse private key: %s", err)
return
}
 
commonName := "test.example.com"
template := Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: commonName,
Organization: []string{"Acme Co"},
},
NotBefore: time.Unix(1000, 0),
NotAfter: time.Unix(100000, 0),
 
SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: KeyUsageCertSign,
 
BasicConstraintsValid: true,
IsCA: true,
DNSNames: []string{"test.example.com"},
 
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
PermittedDNSDomains: []string{".example.com", "example.com"},
}
 
derBytes, err := CreateCertificate(random, &template, &template, &priv.PublicKey, priv)
if err != nil {
t.Errorf("Failed to create certificate: %s", err)
return
}
 
cert, err := ParseCertificate(derBytes)
if err != nil {
t.Errorf("Failed to parse certificate: %s", err)
return
}
 
if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
t.Errorf("Failed to parse policy identifiers: got:%#v want:%#v", cert.PolicyIdentifiers, template.PolicyIdentifiers)
}
 
if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
t.Errorf("Failed to parse name constraints: %#v", cert.PermittedDNSDomains)
}
 
if cert.Subject.CommonName != commonName {
t.Errorf("Subject wasn't correctly copied from the template. Got %s, want %s", cert.Subject.CommonName, commonName)
}
 
if cert.Issuer.CommonName != commonName {
t.Errorf("Issuer wasn't correctly copied from the template. Got %s, want %s", cert.Issuer.CommonName, commonName)
}
 
err = cert.CheckSignatureFrom(cert)
if err != nil {
t.Errorf("Signature verification failed: %s", err)
return
}
}
 
// Self-signed certificate using DSA with SHA1
var dsaCertPem = `-----BEGIN CERTIFICATE-----
MIIEDTCCA82gAwIBAgIJALHPghaoxeDhMAkGByqGSM44BAMweTELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAk5DMQ8wDQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2ds
ZSwgSW5jMRIwEAYDVQQDEwlKb24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFs
bGllQGdvb2dsZS5jb20wHhcNMTEwNTE0MDMwMTQ1WhcNMTEwNjEzMDMwMTQ1WjB5
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTkMxDzANBgNVBAcTBk5ld3RvbjEUMBIG
A1UEChMLR29vZ2xlLCBJbmMxEjAQBgNVBAMTCUpvbiBBbGxpZTEiMCAGCSqGSIb3
DQEJARYTam9uYWxsaWVAZ29vZ2xlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKB
gQC8hLUnQ7FpFYu4WXTj6DKvXvz8QrJkNJCVMTpKAT7uBpobk32S5RrPKXocd4gN
8lyGB9ggS03EVlEwXvSmO0DH2MQtke2jl9j1HLydClMf4sbx5V6TV9IFw505U1iW
jL7awRMgxge+FsudtJK254FjMFo03ZnOQ8ZJJ9E6AEDrlwIVAJpnBn9moyP11Ox5
Asc/5dnjb6dPAoGBAJFHd4KVv1iTVCvEG6gGiYop5DJh28hUQcN9kul+2A0yPUSC
X93oN00P8Vh3eYgSaCWZsha7zDG53MrVJ0Zf6v/X/CoZNhLldeNOepivTRAzn+Rz
kKUYy5l1sxYLHQKF0UGNCXfFKZT0PCmgU+PWhYNBBMn6/cIh44vp85ideo5CA4GE
AAKBgFmifCafzeRaohYKXJgMGSEaggCVCRq5xdyDCat+wbOkjC4mfG01/um3G8u5
LxasjlWRKTR/tcAL7t0QuokVyQaYdVypZXNaMtx1db7YBuHjj3aP+8JOQRI9xz8c
bp5NDJ5pISiFOv4p3GZfqZPcqckDt78AtkQrmnal2txhhjF6o4HeMIHbMB0GA1Ud
DgQWBBQVyyr7hO11ZFFpWX50298Sa3V+rzCBqwYDVR0jBIGjMIGggBQVyyr7hO11
ZFFpWX50298Sa3V+r6F9pHsweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMQ8w
DQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2dsZSwgSW5jMRIwEAYDVQQDEwlK
b24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFsbGllQGdvb2dsZS5jb22CCQCx
z4IWqMXg4TAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUPtn/5j8Q1jJI
7ggOIsgrhgUdjGQCFCsmDq1H11q9+9Wp9IMeGrTSKHIM
-----END CERTIFICATE-----
`
 
func TestParseCertificateWithDsaPublicKey(t *testing.T) {
expectedKey := &dsa.PublicKey{
Parameters: dsa.Parameters{
P: bigFromHexString("00BC84B52743B169158BB85974E3E832AF5EFCFC42B264349095313A4A013EEE069A1B937D92E51ACF297A1C77880DF25C8607D8204B4DC45651305EF4A63B40C7D8C42D91EDA397D8F51CBC9D0A531FE2C6F1E55E9357D205C39D395358968CBEDAC11320C607BE16CB9DB492B6E78163305A34DD99CE43C64927D13A0040EB97"),
Q: bigFromHexString("009A67067F66A323F5D4EC7902C73FE5D9E36FA74F"),
G: bigFromHexString("009147778295BF5893542BC41BA806898A29E43261DBC85441C37D92E97ED80D323D44825FDDE8374D0FF15877798812682599B216BBCC31B9DCCAD527465FEAFFD7FC2A193612E575E34E7A98AF4D10339FE47390A518CB9975B3160B1D0285D1418D0977C52994F43C29A053E3D685834104C9FAFDC221E38BE9F3989D7A8E42"),
},
Y: bigFromHexString("59A27C269FCDE45AA2160A5C980C19211A820095091AB9C5DC8309AB7EC1B3A48C2E267C6D35FEE9B71BCBB92F16AC8E559129347FB5C00BEEDD10BA8915C90698755CA965735A32DC7575BED806E1E38F768FFBC24E41123DC73F1C6E9E4D0C9E692128853AFE29DC665FA993DCA9C903B7BF00B6442B9A76A5DADC6186317A"),
}
pemBlock, _ := pem.Decode([]byte(dsaCertPem))
cert, err := ParseCertificate(pemBlock.Bytes)
if err != nil {
t.Fatalf("Failed to parse certificate: %s", err)
}
if cert.PublicKeyAlgorithm != DSA {
t.Errorf("Parsed key algorithm was not DSA")
}
parsedKey, ok := cert.PublicKey.(*dsa.PublicKey)
if !ok {
t.Fatalf("Parsed key was not a DSA key: %s", err)
}
if expectedKey.Y.Cmp(parsedKey.Y) != 0 ||
expectedKey.P.Cmp(parsedKey.P) != 0 ||
expectedKey.Q.Cmp(parsedKey.Q) != 0 ||
expectedKey.G.Cmp(parsedKey.G) != 0 {
t.Fatal("Parsed key differs from expected key")
}
}
 
func TestParseCertificateWithDSASignatureAlgorithm(t *testing.T) {
pemBlock, _ := pem.Decode([]byte(dsaCertPem))
cert, err := ParseCertificate(pemBlock.Bytes)
if err != nil {
t.Fatalf("Failed to parse certificate: %s", err)
}
if cert.SignatureAlgorithm != DSAWithSHA1 {
t.Errorf("Parsed signature algorithm was not DSAWithSHA1")
}
}
 
func TestVerifyCertificateWithDSASignature(t *testing.T) {
pemBlock, _ := pem.Decode([]byte(dsaCertPem))
cert, err := ParseCertificate(pemBlock.Bytes)
if err != nil {
t.Fatalf("Failed to parse certificate: %s", err)
}
// test cert is self-signed
if err = cert.CheckSignatureFrom(cert); err != nil {
t.Fatalf("DSA Certificate verfication failed: %s", err)
}
}
 
const pemCertificate = `-----BEGIN CERTIFICATE-----
MIIB5DCCAZCgAwIBAgIBATALBgkqhkiG9w0BAQUwLTEQMA4GA1UEChMHQWNtZSBDbzEZMBcGA1UE
AxMQdGVzdC5leGFtcGxlLmNvbTAeFw03MDAxMDEwMDE2NDBaFw03MDAxMDIwMzQ2NDBaMC0xEDAO
BgNVBAoTB0FjbWUgQ28xGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wWjALBgkqhkiG9w0BAQED
SwAwSAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0fd7Ai2KW5ToIwzFo
fvJcS/STa6HA5gQenRUCAwEAAaOBnjCBmzAOBgNVHQ8BAf8EBAMCAAQwDwYDVR0TAQH/BAUwAwEB
/zANBgNVHQ4EBgQEAQIDBDAPBgNVHSMECDAGgAQBAgMEMBsGA1UdEQQUMBKCEHRlc3QuZXhhbXBs
ZS5jb20wDwYDVR0gBAgwBjAEBgIqAzAqBgNVHR4EIzAhoB8wDoIMLmV4YW1wbGUuY29tMA2CC2V4
YW1wbGUuY29tMAsGCSqGSIb3DQEBBQNBAHKZKoS1wEQOGhgklx4+/yFYQlnqwKXvar/ZecQvJwui
0seMQnwBhwdBkHfVIU2Fu5VUMRyxlf0ZNaDXcpU581k=
-----END CERTIFICATE-----`
 
func TestCRLCreation(t *testing.T) {
block, _ := pem.Decode([]byte(pemPrivateKey))
priv, _ := ParsePKCS1PrivateKey(block.Bytes)
block, _ = pem.Decode([]byte(pemCertificate))
cert, _ := ParseCertificate(block.Bytes)
 
now := time.Unix(1000, 0)
expiry := time.Unix(10000, 0)
 
revokedCerts := []pkix.RevokedCertificate{
{
SerialNumber: big.NewInt(1),
RevocationTime: now,
},
{
SerialNumber: big.NewInt(42),
RevocationTime: now,
},
}
 
crlBytes, err := cert.CreateCRL(rand.Reader, priv, revokedCerts, now, expiry)
if err != nil {
t.Errorf("error creating CRL: %s", err)
}
 
_, err = ParseDERCRL(crlBytes)
if err != nil {
t.Errorf("error reparsing CRL: %s", err)
}
}
 
func fromBase64(in string) []byte {
out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
_, err := base64.StdEncoding.Decode(out, []byte(in))
if err != nil {
panic("failed to base64 decode")
}
return out
}
 
func TestParseDERCRL(t *testing.T) {
derBytes := fromBase64(derCRLBase64)
certList, err := ParseDERCRL(derBytes)
if err != nil {
t.Errorf("error parsing: %s", err)
return
}
numCerts := len(certList.TBSCertList.RevokedCertificates)
expected := 88
if numCerts != expected {
t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
}
 
if certList.HasExpired(time.Unix(1302517272, 0)) {
t.Errorf("CRL has expired (but shouldn't have)")
}
 
// Can't check the signature here without a package cycle.
}
 
func TestParsePEMCRL(t *testing.T) {
pemBytes := fromBase64(pemCRLBase64)
certList, err := ParseCRL(pemBytes)
if err != nil {
t.Errorf("error parsing: %s", err)
return
}
numCerts := len(certList.TBSCertList.RevokedCertificates)
expected := 2
if numCerts != expected {
t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
}
 
if certList.HasExpired(time.Unix(1302517272, 0)) {
t.Errorf("CRL has expired (but shouldn't have)")
}
 
// Can't check the signature here without a package cycle.
}
 
const derCRLBase64 = "MIINqzCCDJMCAQEwDQYJKoZIhvcNAQEFBQAwVjEZMBcGA1UEAxMQUEtJIEZJTk1FQ0NBTklDQTEVMBMGA1UEChMMRklOTUVDQ0FOSUNBMRUwEwYDVQQLEwxGSU5NRUNDQU5JQ0ExCzAJBgNVBAYTAklUFw0xMTA1MDQxNjU3NDJaFw0xMTA1MDQyMDU3NDJaMIIMBzAhAg4Ze1od49Lt1qIXBydAzhcNMDkwNzE2MDg0MzIyWjAAMCECDl0HSL9bcZ1Ci/UHJ0DPFw0wOTA3MTYwODQzMTNaMAAwIQIOESB9tVAmX3cY7QcnQNAXDTA5MDcxNjA4NDUyMlowADAhAg4S1tGAQ3mHt8uVBydA1RcNMDkwODA0MTUyNTIyWjAAMCECDlQ249Y7vtC25ScHJ0DWFw0wOTA4MDQxNTI1MzdaMAAwIQIOISMop3NkA4PfYwcnQNkXDTA5MDgwNDExMDAzNFowADAhAg56/BMoS29KEShTBydA2hcNMDkwODA0MTEwMTAzWjAAMCECDnBp/22HPH5CSWoHJ0DbFw0wOTA4MDQxMDU0NDlaMAAwIQIOV9IP+8CD8bK+XAcnQNwXDTA5MDgwNDEwNTcxN1owADAhAg4v5aRz0IxWqYiXBydA3RcNMDkwODA0MTA1NzQ1WjAAMCECDlOU34VzvZAybQwHJ0DeFw0wOTA4MDQxMDU4MjFaMAAwIAINO4CD9lluIxcwBydBAxcNMDkwNzIyMTUzMTU5WjAAMCECDgOllfO8Y1QA7/wHJ0ExFw0wOTA3MjQxMTQxNDNaMAAwIQIOJBX7jbiCdRdyjgcnQUQXDTA5MDkxNjA5MzAwOFowADAhAg5iYSAgmDrlH/RZBydBRRcNMDkwOTE2MDkzMDE3WjAAMCECDmu6k6srP3jcMaQHJ0FRFw0wOTA4MDQxMDU2NDBaMAAwIQIOX8aHlO0V+WVH4QcnQVMXDTA5MDgwNDEwNTcyOVowADAhAg5flK2rg3NnsRgDBydBzhcNMTEwMjAxMTUzMzQ2WjAAMCECDg35yJDL1jOPTgoHJ0HPFw0xMTAyMDExNTM0MjZaMAAwIQIOMyFJ6+e9iiGVBQcnQdAXDTA5MDkxODEzMjAwNVowADAhAg5Emb/Oykucmn8fBydB1xcNMDkwOTIxMTAxMDQ3WjAAMCECDjQKCncV+MnUavMHJ0HaFw0wOTA5MjIwODE1MjZaMAAwIQIOaxiFUt3dpd+tPwcnQfQXDTEwMDYxODA4NDI1MVowADAhAg5G7P8nO0tkrMt7BydB9RcNMTAwNjE4MDg0MjMwWjAAMCECDmTCC3SXhmDRst4HJ0H2Fw0wOTA5MjgxMjA3MjBaMAAwIQIOHoGhUr/pRwzTKgcnQfcXDTA5MDkyODEyMDcyNFowADAhAg50wrcrCiw8mQmPBydCBBcNMTAwMjE2MTMwMTA2WjAAMCECDifWmkvwyhEqwEcHJ0IFFw0xMDAyMTYxMzAxMjBaMAAwIQIOfgPmlW9fg+osNgcnQhwXDTEwMDQxMzA5NTIwMFowADAhAg4YHAGuA6LgCk7tBydCHRcNMTAwNDEzMDk1MTM4WjAAMCECDi1zH1bxkNJhokAHJ0IsFw0xMDA0MTMwOTU5MzBaMAAwIQIOMipNccsb/wo2fwcnQi0XDTEwMDQxMzA5NTkwMFowADAhAg46lCmvPl4GpP6ABydCShcNMTAwMTE5MDk1MjE3WjAAMCECDjaTcaj+wBpcGAsHJ0JLFw0xMDAxMTkwOTUyMzRaMAAwIQIOOMC13EOrBuxIOQcnQloXDTEwMDIwMTA5NDcwNVowADAhAg5KmZl+krz4RsmrBydCWxcNMTAwMjAxMDk0NjQwWjAAMCECDmLG3zQJ/fzdSsUHJ0JiFw0xMDAzMDEwOTUxNDBaMAAwIQIOP39ksgHdojf4owcnQmMXDTEwMDMwMTA5NTExN1owADAhAg4LDQzvWNRlD6v9BydCZBcNMTAwMzAxMDk0NjIyWjAAMCECDkmNfeclaFhIaaUHJ0JlFw0xMDAzMDEwOTQ2MDVaMAAwIQIOT/qWWfpH/m8NTwcnQpQXDTEwMDUxMTA5MTgyMVowADAhAg5m/ksYxvCEgJSvBydClRcNMTAwNTExMDkxODAxWjAAMCECDgvf3Ohq6JOPU9AHJ0KWFw0xMDA1MTEwOTIxMjNaMAAwIQIOKSPas10z4jNVIQcnQpcXDTEwMDUxMTA5MjEwMlowADAhAg4mCWmhoZ3lyKCDBydCohcNMTEwNDI4MTEwMjI1WjAAMCECDkeiyRsBMK0Gvr4HJ0KjFw0xMTA0MjgxMTAyMDdaMAAwIQIOa09b/nH2+55SSwcnQq4XDTExMDQwMTA4Mjk0NlowADAhAg5O7M7iq7gGplr1BydCrxcNMTEwNDAxMDgzMDE3WjAAMCECDjlT6mJxUjTvyogHJ0K1Fw0xMTAxMjcxNTQ4NTJaMAAwIQIODS/l4UUFLe21NAcnQrYXDTExMDEyNzE1NDgyOFowADAhAg5lPRA0XdOUF6lSBydDHhcNMTEwMTI4MTQzNTA1WjAAMCECDixKX4fFGGpENwgHJ0MfFw0xMTAxMjgxNDM1MzBaMAAwIQIORNBkqsPnpKTtbAcnQ08XDTEwMDkwOTA4NDg0MlowADAhAg5QL+EMM3lohedEBydDUBcNMTAwOTA5MDg0ODE5WjAAMCECDlhDnHK+HiTRAXcHJ0NUFw0xMDEwMTkxNjIxNDBaMAAwIQIOdBFqAzq/INz53gcnQ1UXDTEwMTAxOTE2MjA0NFowADAhAg4OjR7s8MgKles1BydDWhcNMTEwMTI3MTY1MzM2WjAAMCECDmfR/elHee+d0SoHJ0NbFw0xMTAxMjcxNjUzNTZaMAAwIQIOBTKv2ui+KFMI+wcnQ5YXDTEwMDkxNTEwMjE1N1owADAhAg49F3c/GSah+oRUBydDmxcNMTEwMTI3MTczMjMzWjAAMCECDggv4I61WwpKFMMHJ0OcFw0xMTAxMjcxNzMyNTVaMAAwIQIOXx/Y8sEvwS10LAcnQ6UXDTExMDEyODExMjkzN1owADAhAg5LSLbnVrSKaw/9BydDphcNMTEwMTI4MTEyOTIwWjAAMCECDmFFoCuhKUeACQQHJ0PfFw0xMTAxMTExMDE3MzdaMAAwIQIOQTDdFh2fSPF6AAcnQ+AXDTExMDExMTEwMTcxMFowADAhAg5B8AOXX61FpvbbBydD5RcNMTAxMDA2MTAxNDM2WjAAMCECDh41P2Gmi7PkwI4HJ0PmFw0xMDEwMDYxMDE2MjVaMAAwIQIOWUHGLQCd+Ale9gcnQ/0XDTExMDUwMjA3NTYxMFowADAhAg5Z2c9AYkikmgWOBydD/hcNMTEwNTAyMDc1NjM0WjAAMCECDmf/UD+/h8nf+74HJ0QVFw0xMTA0MTUwNzI4MzNaMAAwIQIOICvj4epy3MrqfwcnRBYXDTExMDQxNTA3Mjg1NlowADAhAg4bouRMfOYqgv4xBydEHxcNMTEwMzA4MTYyNDI1WjAAMCECDhebWHGoKiTp7pEHJ0QgFw0xMTAzMDgxNjI0NDhaMAAwIQIOX+qnxxAqJ8LtawcnRDcXDTExMDEzMTE1MTIyOFowADAhAg4j0fICqZ+wkOdqBydEOBcNMTEwMTMxMTUxMTQxWjAAMCECDhmXjsV4SUpWtAMHJ0RLFw0xMTAxMjgxMTI0MTJaMAAwIQIODno/w+zG43kkTwcnREwXDTExMDEyODExMjM1MlowADAhAg4b1gc88767Fr+LBydETxcNMTEwMTI4MTEwMjA4WjAAMCECDn+M3Pa1w2nyFeUHJ0RQFw0xMTAxMjgxMDU4NDVaMAAwIQIOaduoyIH61tqybAcnRJUXDTEwMTIxNTA5NDMyMlowADAhAg4nLqQPkyi3ESAKBydElhcNMTAxMjE1MDk0MzM2WjAAMCECDi504NIMH8578gQHJ0SbFw0xMTAyMTQxNDA1NDFaMAAwIQIOGuaM8PDaC5u1egcnRJwXDTExMDIxNDE0MDYwNFowADAhAg4ehYq/BXGnB5PWBydEnxcNMTEwMjA0MDgwOTUxWjAAMCECDkSD4eS4FxW5H20HJ0SgFw0xMTAyMDQwODA5MjVaMAAwIQIOOCcb6ilYObt1egcnRKEXDTExMDEyNjEwNDEyOVowADAhAg58tISWCCwFnKGnBydEohcNMTEwMjA0MDgxMzQyWjAAMCECDn5rjtabY/L/WL0HJ0TJFw0xMTAyMDQxMTAzNDFaMAAwDQYJKoZIhvcNAQEFBQADggEBAGnF2Gs0+LNiYCW1Ipm83OXQYP/bd5tFFRzyz3iepFqNfYs4D68/QihjFoRHQoXEB0OEe1tvaVnnPGnEOpi6krwekquMxo4H88B5SlyiFIqemCOIss0SxlCFs69LmfRYvPPvPEhoXtQ3ZThe0UvKG83GOklhvGl6OaiRf4Mt+m8zOT4Wox/j6aOBK6cw6qKCdmD+Yj1rrNqFGg1CnSWMoD6S6mwNgkzwdBUJZ22BwrzAAo4RHa2Uy3ef1FjwD0XtU5N3uDSxGGBEDvOe5z82rps3E22FpAA8eYl8kaXtmWqyvYU0epp4brGuTxCuBMCAsxt/OjIjeNNQbBGkwxgfYA0="
 
const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNakUwDQpNalExTlZvd1BnSVJBTEd6blowOTVQQjVhQU9MUGc1N2ZNTVhEVEF5TVRBeU16RTBOVEF4TkZvd0dqQVlCZ05WDQpIUmdFRVJnUE1qQXdNakV3TWpNeE5EVXdNVFJhb0RBd0xqQWZCZ05WSFNNRUdEQVdnQlQxVERGNlVRTS9MTmVMDQpsNWx2cUhHUXEzZzltekFMQmdOVkhSUUVCQUlDQUlRd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ1lFQUZVNUFzNk16DQpxNVBSc2lmYW9iUVBHaDFhSkx5QytNczVBZ2MwYld5QTNHQWR4dXI1U3BQWmVSV0NCamlQL01FSEJXSkNsQkhQDQpHUmNxNXlJZDNFakRrYUV5eFJhK2k2N0x6dmhJNmMyOUVlNks5cFNZd2ppLzdSVWhtbW5Qclh0VHhsTDBsckxyDQptUVFKNnhoRFJhNUczUUE0Q21VZHNITnZicnpnbUNZcHZWRT0NCi0tLS0tRU5EIFg1MDkgQ1JMLS0tLS0NCg0K"
/x509/x509.go
0,0 → 1,1070
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package x509 parses X.509-encoded keys and certificates.
package x509
 
import (
"bytes"
"crypto"
"crypto/dsa"
"crypto/rsa"
"crypto/sha1"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"errors"
"io"
"math/big"
"time"
)
 
// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo
// in RFC 3280.
type pkixPublicKey struct {
Algo pkix.AlgorithmIdentifier
BitString asn1.BitString
}
 
// ParsePKIXPublicKey parses a DER encoded public key. These values are
// typically found in PEM blocks with "BEGIN PUBLIC KEY".
func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
var pki publicKeyInfo
if _, err = asn1.Unmarshal(derBytes, &pki); err != nil {
return
}
algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
if algo == UnknownPublicKeyAlgorithm {
return nil, errors.New("ParsePKIXPublicKey: unknown public key algorithm")
}
return parsePublicKey(algo, &pki)
}
 
// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format.
func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
var pubBytes []byte
 
switch pub := pub.(type) {
case *rsa.PublicKey:
pubBytes, _ = asn1.Marshal(rsaPublicKey{
N: pub.N,
E: pub.E,
})
default:
return nil, errors.New("MarshalPKIXPublicKey: unknown public key type")
}
 
pkix := pkixPublicKey{
Algo: pkix.AlgorithmIdentifier{
Algorithm: []int{1, 2, 840, 113549, 1, 1, 1},
// This is a NULL parameters value which is technically
// superfluous, but most other code includes it and, by
// doing this, we match their public key hashes.
Parameters: asn1.RawValue{
Tag: 5,
},
},
BitString: asn1.BitString{
Bytes: pubBytes,
BitLength: 8 * len(pubBytes),
},
}
 
ret, _ := asn1.Marshal(pkix)
return ret, nil
}
 
// These structures reflect the ASN.1 structure of X.509 certificates.:
 
type certificate struct {
Raw asn1.RawContent
TBSCertificate tbsCertificate
SignatureAlgorithm pkix.AlgorithmIdentifier
SignatureValue asn1.BitString
}
 
type tbsCertificate struct {
Raw asn1.RawContent
Version int `asn1:"optional,explicit,default:1,tag:0"`
SerialNumber *big.Int
SignatureAlgorithm pkix.AlgorithmIdentifier
Issuer asn1.RawValue
Validity validity
Subject asn1.RawValue
PublicKey publicKeyInfo
UniqueId asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"`
}
 
type dsaAlgorithmParameters struct {
P, Q, G *big.Int
}
 
type dsaSignature struct {
R, S *big.Int
}
 
type validity struct {
NotBefore, NotAfter time.Time
}
 
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
 
// RFC 5280, 4.2.1.1
type authKeyId struct {
Id []byte `asn1:"optional,tag:0"`
}
 
type SignatureAlgorithm int
 
const (
UnknownSignatureAlgorithm SignatureAlgorithm = iota
MD2WithRSA
MD5WithRSA
SHA1WithRSA
SHA256WithRSA
SHA384WithRSA
SHA512WithRSA
DSAWithSHA1
DSAWithSHA256
)
 
type PublicKeyAlgorithm int
 
const (
UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
RSA
DSA
)
 
// OIDs for signature algorithms
//
// pkcs-1 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
//
//
// RFC 3279 2.2.1 RSA Signature Algorithms
//
// md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
//
// md5WithRSAEncryption OBJECT IDENTIFER ::= { pkcs-1 4 }
//
// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
//
// dsaWithSha1 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
//
//
// RFC 4055 5 PKCS #1 Version 1.5
//
// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
//
// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
//
// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
//
//
// RFC 5758 3.1 DSA Signature Algorithms
//
// dsaWithSha356 OBJECT IDENTIFER ::= {
// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
// algorithms(4) id-dsa-with-sha2(3) 2}
//
var (
oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 4, 3, 2}
)
 
func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) SignatureAlgorithm {
switch {
case oid.Equal(oidSignatureMD2WithRSA):
return MD2WithRSA
case oid.Equal(oidSignatureMD5WithRSA):
return MD5WithRSA
case oid.Equal(oidSignatureSHA1WithRSA):
return SHA1WithRSA
case oid.Equal(oidSignatureSHA256WithRSA):
return SHA256WithRSA
case oid.Equal(oidSignatureSHA384WithRSA):
return SHA384WithRSA
case oid.Equal(oidSignatureSHA512WithRSA):
return SHA512WithRSA
case oid.Equal(oidSignatureDSAWithSHA1):
return DSAWithSHA1
case oid.Equal(oidSignatureDSAWithSHA256):
return DSAWithSHA256
}
return UnknownSignatureAlgorithm
}
 
// RFC 3279, 2.3 Public Key Algorithms
//
// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
// rsadsi(113549) pkcs(1) 1 }
//
// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
//
// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
// x9-57(10040) x9cm(4) 1 }
var (
oidPublicKeyRsa = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
oidPublicKeyDsa = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
)
 
func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
switch {
case oid.Equal(oidPublicKeyRsa):
return RSA
case oid.Equal(oidPublicKeyDsa):
return DSA
}
return UnknownPublicKeyAlgorithm
}
 
// KeyUsage represents the set of actions that are valid for a given key. It's
// a bitmap of the KeyUsage* constants.
type KeyUsage int
 
const (
KeyUsageDigitalSignature KeyUsage = 1 << iota
KeyUsageContentCommitment
KeyUsageKeyEncipherment
KeyUsageDataEncipherment
KeyUsageKeyAgreement
KeyUsageCertSign
KeyUsageCRLSign
KeyUsageEncipherOnly
KeyUsageDecipherOnly
)
 
// RFC 5280, 4.2.1.12 Extended Key Usage
//
// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
//
// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
//
// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
var (
oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
)
 
// ExtKeyUsage represents an extended set of actions that are valid for a given key.
// Each of the ExtKeyUsage* constants define a unique action.
type ExtKeyUsage int
 
const (
ExtKeyUsageAny ExtKeyUsage = iota
ExtKeyUsageServerAuth
ExtKeyUsageClientAuth
ExtKeyUsageCodeSigning
ExtKeyUsageEmailProtection
ExtKeyUsageTimeStamping
ExtKeyUsageOCSPSigning
)
 
// A Certificate represents an X.509 certificate.
type Certificate struct {
Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content.
RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
RawSubject []byte // DER encoded Subject
RawIssuer []byte // DER encoded Issuer
 
Signature []byte
SignatureAlgorithm SignatureAlgorithm
 
PublicKeyAlgorithm PublicKeyAlgorithm
PublicKey interface{}
 
Version int
SerialNumber *big.Int
Issuer pkix.Name
Subject pkix.Name
NotBefore, NotAfter time.Time // Validity bounds.
KeyUsage KeyUsage
 
ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages.
UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
 
BasicConstraintsValid bool // if true then the next two fields are valid.
IsCA bool
MaxPathLen int
 
SubjectKeyId []byte
AuthorityKeyId []byte
 
// Subject Alternate Name values
DNSNames []string
EmailAddresses []string
 
// Name constraints
PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
PermittedDNSDomains []string
 
PolicyIdentifiers []asn1.ObjectIdentifier
}
 
// UnsupportedAlgorithmError results from attempting to perform an operation
// that involves algorithms that are not currently implemented.
type UnsupportedAlgorithmError struct{}
 
func (UnsupportedAlgorithmError) Error() string {
return "cannot verify signature: algorithm unimplemented"
}
 
// ConstraintViolationError results when a requested usage is not permitted by
// a certificate. For example: checking a signature when the public key isn't a
// certificate signing key.
type ConstraintViolationError struct{}
 
func (ConstraintViolationError) Error() string {
return "invalid signature: parent certificate cannot sign this kind of certificate"
}
 
func (c *Certificate) Equal(other *Certificate) bool {
return bytes.Equal(c.Raw, other.Raw)
}
 
// CheckSignatureFrom verifies that the signature on c is a valid signature
// from parent.
func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
// RFC 5280, 4.2.1.9:
// "If the basic constraints extension is not present in a version 3
// certificate, or the extension is present but the cA boolean is not
// asserted, then the certified public key MUST NOT be used to verify
// certificate signatures."
if parent.Version == 3 && !parent.BasicConstraintsValid ||
parent.BasicConstraintsValid && !parent.IsCA {
return ConstraintViolationError{}
}
 
if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {
return ConstraintViolationError{}
}
 
if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
return UnsupportedAlgorithmError{}
}
 
// TODO(agl): don't ignore the path length constraint.
 
return parent.CheckSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature)
}
 
// CheckSignature verifies that signature is a valid signature over signed from
// c's public key.
func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) {
var hashType crypto.Hash
 
switch algo {
case SHA1WithRSA, DSAWithSHA1:
hashType = crypto.SHA1
case SHA256WithRSA, DSAWithSHA256:
hashType = crypto.SHA256
case SHA384WithRSA:
hashType = crypto.SHA384
case SHA512WithRSA:
hashType = crypto.SHA512
default:
return UnsupportedAlgorithmError{}
}
 
h := hashType.New()
if h == nil {
return UnsupportedAlgorithmError{}
}
 
h.Write(signed)
digest := h.Sum(nil)
 
switch pub := c.PublicKey.(type) {
case *rsa.PublicKey:
return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
case *dsa.PublicKey:
dsaSig := new(dsaSignature)
if _, err := asn1.Unmarshal(signature, dsaSig); err != nil {
return err
}
if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
return errors.New("DSA signature contained zero or negative values")
}
if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
return errors.New("DSA verification failure")
}
return
}
return UnsupportedAlgorithmError{}
}
 
// CheckCRLSignature checks that the signature in crl is from c.
func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) (err error) {
algo := getSignatureAlgorithmFromOID(crl.SignatureAlgorithm.Algorithm)
return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())
}
 
type UnhandledCriticalExtension struct{}
 
func (h UnhandledCriticalExtension) Error() string {
return "unhandled critical extension"
}
 
type basicConstraints struct {
IsCA bool `asn1:"optional"`
MaxPathLen int `asn1:"optional"`
}
 
// RFC 5280 4.2.1.4
type policyInformation struct {
Policy asn1.ObjectIdentifier
// policyQualifiers omitted
}
 
// RFC 5280, 4.2.1.10
type nameConstraints struct {
Permitted []generalSubtree `asn1:"optional,tag:0"`
Excluded []generalSubtree `asn1:"optional,tag:1"`
}
 
type generalSubtree struct {
Name string `asn1:"tag:2,optional,ia5"`
Min int `asn1:"optional,tag:0"`
Max int `asn1:"optional,tag:1"`
}
 
func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
asn1Data := keyData.PublicKey.RightAlign()
switch algo {
case RSA:
p := new(rsaPublicKey)
_, err := asn1.Unmarshal(asn1Data, p)
if err != nil {
return nil, err
}
 
pub := &rsa.PublicKey{
E: p.E,
N: p.N,
}
return pub, nil
case DSA:
var p *big.Int
_, err := asn1.Unmarshal(asn1Data, &p)
if err != nil {
return nil, err
}
paramsData := keyData.Algorithm.Parameters.FullBytes
params := new(dsaAlgorithmParameters)
_, err = asn1.Unmarshal(paramsData, params)
if err != nil {
return nil, err
}
if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 {
return nil, errors.New("zero or negative DSA parameter")
}
pub := &dsa.PublicKey{
Parameters: dsa.Parameters{
P: params.P,
Q: params.Q,
G: params.G,
},
Y: p,
}
return pub, nil
default:
return nil, nil
}
panic("unreachable")
}
 
func parseCertificate(in *certificate) (*Certificate, error) {
out := new(Certificate)
out.Raw = in.Raw
out.RawTBSCertificate = in.TBSCertificate.Raw
out.RawSubjectPublicKeyInfo = in.TBSCertificate.PublicKey.Raw
out.RawSubject = in.TBSCertificate.Subject.FullBytes
out.RawIssuer = in.TBSCertificate.Issuer.FullBytes
 
out.Signature = in.SignatureValue.RightAlign()
out.SignatureAlgorithm =
getSignatureAlgorithmFromOID(in.TBSCertificate.SignatureAlgorithm.Algorithm)
 
out.PublicKeyAlgorithm =
getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm)
var err error
out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey)
if err != nil {
return nil, err
}
 
if in.TBSCertificate.SerialNumber.Sign() < 0 {
return nil, errors.New("negative serial number")
}
 
out.Version = in.TBSCertificate.Version + 1
out.SerialNumber = in.TBSCertificate.SerialNumber
 
var issuer, subject pkix.RDNSequence
if _, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil {
return nil, err
}
if _, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil {
return nil, err
}
 
out.Issuer.FillFromRDNSequence(&issuer)
out.Subject.FillFromRDNSequence(&subject)
 
out.NotBefore = in.TBSCertificate.Validity.NotBefore
out.NotAfter = in.TBSCertificate.Validity.NotAfter
 
for _, e := range in.TBSCertificate.Extensions {
if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
switch e.Id[3] {
case 15:
// RFC 5280, 4.2.1.3
var usageBits asn1.BitString
_, err := asn1.Unmarshal(e.Value, &usageBits)
 
if err == nil {
var usage int
for i := 0; i < 9; i++ {
if usageBits.At(i) != 0 {
usage |= 1 << uint(i)
}
}
out.KeyUsage = KeyUsage(usage)
continue
}
case 19:
// RFC 5280, 4.2.1.9
var constraints basicConstraints
_, err := asn1.Unmarshal(e.Value, &constraints)
 
if err == nil {
out.BasicConstraintsValid = true
out.IsCA = constraints.IsCA
out.MaxPathLen = constraints.MaxPathLen
continue
}
case 17:
// RFC 5280, 4.2.1.6
 
// SubjectAltName ::= GeneralNames
//
// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
//
// GeneralName ::= CHOICE {
// otherName [0] OtherName,
// rfc822Name [1] IA5String,
// dNSName [2] IA5String,
// x400Address [3] ORAddress,
// directoryName [4] Name,
// ediPartyName [5] EDIPartyName,
// uniformResourceIdentifier [6] IA5String,
// iPAddress [7] OCTET STRING,
// registeredID [8] OBJECT IDENTIFIER }
var seq asn1.RawValue
_, err := asn1.Unmarshal(e.Value, &seq)
if err != nil {
return nil, err
}
if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
return nil, asn1.StructuralError{Msg: "bad SAN sequence"}
}
 
parsedName := false
 
rest := seq.Bytes
for len(rest) > 0 {
var v asn1.RawValue
rest, err = asn1.Unmarshal(rest, &v)
if err != nil {
return nil, err
}
switch v.Tag {
case 1:
out.EmailAddresses = append(out.EmailAddresses, string(v.Bytes))
parsedName = true
case 2:
out.DNSNames = append(out.DNSNames, string(v.Bytes))
parsedName = true
}
}
 
if parsedName {
continue
}
// If we didn't parse any of the names then we
// fall through to the critical check below.
 
case 30:
// RFC 5280, 4.2.1.10
 
// NameConstraints ::= SEQUENCE {
// permittedSubtrees [0] GeneralSubtrees OPTIONAL,
// excludedSubtrees [1] GeneralSubtrees OPTIONAL }
//
// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
//
// GeneralSubtree ::= SEQUENCE {
// base GeneralName,
// minimum [0] BaseDistance DEFAULT 0,
// maximum [1] BaseDistance OPTIONAL }
//
// BaseDistance ::= INTEGER (0..MAX)
 
var constraints nameConstraints
_, err := asn1.Unmarshal(e.Value, &constraints)
if err != nil {
return nil, err
}
 
if len(constraints.Excluded) > 0 && e.Critical {
return out, UnhandledCriticalExtension{}
}
 
for _, subtree := range constraints.Permitted {
if subtree.Min > 0 || subtree.Max > 0 || len(subtree.Name) == 0 {
if e.Critical {
return out, UnhandledCriticalExtension{}
}
continue
}
out.PermittedDNSDomains = append(out.PermittedDNSDomains, subtree.Name)
}
continue
 
case 35:
// RFC 5280, 4.2.1.1
var a authKeyId
_, err = asn1.Unmarshal(e.Value, &a)
if err != nil {
return nil, err
}
out.AuthorityKeyId = a.Id
continue
 
case 37:
// RFC 5280, 4.2.1.12. Extended Key Usage
 
// id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
//
// ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
//
// KeyPurposeId ::= OBJECT IDENTIFIER
 
var keyUsage []asn1.ObjectIdentifier
_, err = asn1.Unmarshal(e.Value, &keyUsage)
if err != nil {
return nil, err
}
 
for _, u := range keyUsage {
switch {
case u.Equal(oidExtKeyUsageAny):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageAny)
case u.Equal(oidExtKeyUsageServerAuth):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageServerAuth)
case u.Equal(oidExtKeyUsageClientAuth):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageClientAuth)
case u.Equal(oidExtKeyUsageCodeSigning):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageCodeSigning)
case u.Equal(oidExtKeyUsageEmailProtection):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageEmailProtection)
case u.Equal(oidExtKeyUsageTimeStamping):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageTimeStamping)
case u.Equal(oidExtKeyUsageOCSPSigning):
out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageOCSPSigning)
default:
out.UnknownExtKeyUsage = append(out.UnknownExtKeyUsage, u)
}
}
 
continue
 
case 14:
// RFC 5280, 4.2.1.2
var keyid []byte
_, err = asn1.Unmarshal(e.Value, &keyid)
if err != nil {
return nil, err
}
out.SubjectKeyId = keyid
continue
 
case 32:
// RFC 5280 4.2.1.4: Certificate Policies
var policies []policyInformation
if _, err = asn1.Unmarshal(e.Value, &policies); err != nil {
return nil, err
}
out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies))
for i, policy := range policies {
out.PolicyIdentifiers[i] = policy.Policy
}
}
}
 
if e.Critical {
return out, UnhandledCriticalExtension{}
}
}
 
return out, nil
}
 
// ParseCertificate parses a single certificate from the given ASN.1 DER data.
func ParseCertificate(asn1Data []byte) (*Certificate, error) {
var cert certificate
rest, err := asn1.Unmarshal(asn1Data, &cert)
if err != nil {
return nil, err
}
if len(rest) > 0 {
return nil, asn1.SyntaxError{Msg: "trailing data"}
}
 
return parseCertificate(&cert)
}
 
// ParseCertificates parses one or more certificates from the given ASN.1 DER
// data. The certificates must be concatenated with no intermediate padding.
func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
var v []*certificate
 
for len(asn1Data) > 0 {
cert := new(certificate)
var err error
asn1Data, err = asn1.Unmarshal(asn1Data, cert)
if err != nil {
return nil, err
}
v = append(v, cert)
}
 
ret := make([]*Certificate, len(v))
for i, ci := range v {
cert, err := parseCertificate(ci)
if err != nil {
return nil, err
}
ret[i] = cert
}
 
return ret, nil
}
 
func reverseBitsInAByte(in byte) byte {
b1 := in>>4 | in<<4
b2 := b1>>2&0x33 | b1<<2&0xcc
b3 := b2>>1&0x55 | b2<<1&0xaa
return b3
}
 
var (
oidExtensionSubjectKeyId = []int{2, 5, 29, 14}
oidExtensionKeyUsage = []int{2, 5, 29, 15}
oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}
oidExtensionBasicConstraints = []int{2, 5, 29, 19}
oidExtensionSubjectAltName = []int{2, 5, 29, 17}
oidExtensionCertificatePolicies = []int{2, 5, 29, 32}
oidExtensionNameConstraints = []int{2, 5, 29, 30}
)
 
func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
ret = make([]pkix.Extension, 7 /* maximum number of elements. */ )
n := 0
 
if template.KeyUsage != 0 {
ret[n].Id = oidExtensionKeyUsage
ret[n].Critical = true
 
var a [2]byte
a[0] = reverseBitsInAByte(byte(template.KeyUsage))
a[1] = reverseBitsInAByte(byte(template.KeyUsage >> 8))
 
l := 1
if a[1] != 0 {
l = 2
}
 
ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: a[0:l], BitLength: l * 8})
if err != nil {
return
}
n++
}
 
if template.BasicConstraintsValid {
ret[n].Id = oidExtensionBasicConstraints
ret[n].Value, err = asn1.Marshal(basicConstraints{template.IsCA, template.MaxPathLen})
ret[n].Critical = true
if err != nil {
return
}
n++
}
 
if len(template.SubjectKeyId) > 0 {
ret[n].Id = oidExtensionSubjectKeyId
ret[n].Value, err = asn1.Marshal(template.SubjectKeyId)
if err != nil {
return
}
n++
}
 
if len(template.AuthorityKeyId) > 0 {
ret[n].Id = oidExtensionAuthorityKeyId
ret[n].Value, err = asn1.Marshal(authKeyId{template.AuthorityKeyId})
if err != nil {
return
}
n++
}
 
if len(template.DNSNames) > 0 {
ret[n].Id = oidExtensionSubjectAltName
rawValues := make([]asn1.RawValue, len(template.DNSNames))
for i, name := range template.DNSNames {
rawValues[i] = asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)}
}
ret[n].Value, err = asn1.Marshal(rawValues)
if err != nil {
return
}
n++
}
 
if len(template.PolicyIdentifiers) > 0 {
ret[n].Id = oidExtensionCertificatePolicies
policies := make([]policyInformation, len(template.PolicyIdentifiers))
for i, policy := range template.PolicyIdentifiers {
policies[i].Policy = policy
}
ret[n].Value, err = asn1.Marshal(policies)
if err != nil {
return
}
n++
}
 
if len(template.PermittedDNSDomains) > 0 {
ret[n].Id = oidExtensionNameConstraints
ret[n].Critical = template.PermittedDNSDomainsCritical
 
var out nameConstraints
out.Permitted = make([]generalSubtree, len(template.PermittedDNSDomains))
for i, permitted := range template.PermittedDNSDomains {
out.Permitted[i] = generalSubtree{Name: permitted}
}
ret[n].Value, err = asn1.Marshal(out)
if err != nil {
return
}
n++
}
 
// Adding another extension here? Remember to update the maximum number
// of elements in the make() at the top of the function.
 
return ret[0:n], nil
}
 
var (
oidSHA1WithRSA = []int{1, 2, 840, 113549, 1, 1, 5}
oidRSA = []int{1, 2, 840, 113549, 1, 1, 1}
)
 
func subjectBytes(cert *Certificate) ([]byte, error) {
if len(cert.RawSubject) > 0 {
return cert.RawSubject, nil
}
 
return asn1.Marshal(cert.Subject.ToRDNSequence())
}
 
// CreateCertificate creates a new certificate based on a template. The
// following members of template are used: SerialNumber, Subject, NotBefore,
// NotAfter, KeyUsage, BasicConstraintsValid, IsCA, MaxPathLen, SubjectKeyId,
// DNSNames, PermittedDNSDomainsCritical, PermittedDNSDomains.
//
// The certificate is signed by parent. If parent is equal to template then the
// certificate is self-signed. The parameter pub is the public key of the
// signee and priv is the private key of the signer.
//
// The returned slice is the certificate in DER encoding.
//
// The only supported key type is RSA (*rsa.PublicKey for pub, *rsa.PrivateKey
// for priv).
func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) {
rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("x509: non-RSA public keys not supported")
}
 
rsaPriv, ok := priv.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("x509: non-RSA private keys not supported")
}
 
asn1PublicKey, err := asn1.Marshal(rsaPublicKey{
N: rsaPub.N,
E: rsaPub.E,
})
if err != nil {
return
}
 
if len(parent.SubjectKeyId) > 0 {
template.AuthorityKeyId = parent.SubjectKeyId
}
 
extensions, err := buildExtensions(template)
if err != nil {
return
}
 
asn1Issuer, err := subjectBytes(parent)
if err != nil {
return
}
 
asn1Subject, err := subjectBytes(template)
if err != nil {
return
}
 
encodedPublicKey := asn1.BitString{BitLength: len(asn1PublicKey) * 8, Bytes: asn1PublicKey}
c := tbsCertificate{
Version: 2,
SerialNumber: template.SerialNumber,
SignatureAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidSHA1WithRSA},
Issuer: asn1.RawValue{FullBytes: asn1Issuer},
Validity: validity{template.NotBefore, template.NotAfter},
Subject: asn1.RawValue{FullBytes: asn1Subject},
PublicKey: publicKeyInfo{nil, pkix.AlgorithmIdentifier{Algorithm: oidRSA}, encodedPublicKey},
Extensions: extensions,
}
 
tbsCertContents, err := asn1.Marshal(c)
if err != nil {
return
}
 
c.Raw = tbsCertContents
 
h := sha1.New()
h.Write(tbsCertContents)
digest := h.Sum(nil)
 
signature, err := rsa.SignPKCS1v15(rand, rsaPriv, crypto.SHA1, digest)
if err != nil {
return
}
 
cert, err = asn1.Marshal(certificate{
nil,
c,
pkix.AlgorithmIdentifier{Algorithm: oidSHA1WithRSA},
asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
})
return
}
 
// pemCRLPrefix is the magic string that indicates that we have a PEM encoded
// CRL.
var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
 
// pemType is the type of a PEM encoded CRL.
var pemType = "X509 CRL"
 
// ParseCRL parses a CRL from the given bytes. It's often the case that PEM
// encoded CRLs will appear where they should be DER encoded, so this function
// will transparently handle PEM encoding as long as there isn't any leading
// garbage.
func ParseCRL(crlBytes []byte) (certList *pkix.CertificateList, err error) {
if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
block, _ := pem.Decode(crlBytes)
if block != nil && block.Type == pemType {
crlBytes = block.Bytes
}
}
return ParseDERCRL(crlBytes)
}
 
// ParseDERCRL parses a DER encoded CRL from the given bytes.
func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) {
certList = new(pkix.CertificateList)
_, err = asn1.Unmarshal(derBytes, certList)
if err != nil {
certList = nil
}
return
}
 
// CreateCRL returns a DER encoded CRL, signed by this Certificate, that
// contains the given list of revoked certificates.
//
// The only supported key type is RSA (*rsa.PrivateKey for priv).
func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {
rsaPriv, ok := priv.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("x509: non-RSA private keys not supported")
}
tbsCertList := pkix.TBSCertificateList{
Version: 2,
Signature: pkix.AlgorithmIdentifier{
Algorithm: oidSignatureSHA1WithRSA,
},
Issuer: c.Subject.ToRDNSequence(),
ThisUpdate: now,
NextUpdate: expiry,
RevokedCertificates: revokedCerts,
}
 
tbsCertListContents, err := asn1.Marshal(tbsCertList)
if err != nil {
return
}
 
h := sha1.New()
h.Write(tbsCertListContents)
digest := h.Sum(nil)
 
signature, err := rsa.SignPKCS1v15(rand, rsaPriv, crypto.SHA1, digest)
if err != nil {
return
}
 
return asn1.Marshal(pkix.CertificateList{
TBSCertList: tbsCertList,
SignatureAlgorithm: pkix.AlgorithmIdentifier{
Algorithm: oidSignatureSHA1WithRSA,
},
SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
})
}
/x509/cert_pool.go
0,0 → 1,113
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"encoding/pem"
)
 
// CertPool is a set of certificates.
type CertPool struct {
bySubjectKeyId map[string][]int
byName map[string][]int
certs []*Certificate
}
 
// NewCertPool returns a new, empty CertPool.
func NewCertPool() *CertPool {
return &CertPool{
make(map[string][]int),
make(map[string][]int),
nil,
}
}
 
// findVerifiedParents attempts to find certificates in s which have signed the
// given certificate. If no such certificate can be found or the signature
// doesn't match, it returns nil.
func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int) {
if s == nil {
return
}
var candidates []int
 
if len(cert.AuthorityKeyId) > 0 {
candidates = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
}
if len(candidates) == 0 {
candidates = s.byName[string(cert.RawIssuer)]
}
 
for _, c := range candidates {
if cert.CheckSignatureFrom(s.certs[c]) == nil {
parents = append(parents, c)
}
}
 
return
}
 
// AddCert adds a certificate to a pool.
func (s *CertPool) AddCert(cert *Certificate) {
if cert == nil {
panic("adding nil Certificate to CertPool")
}
 
// Check that the certificate isn't being added twice.
for _, c := range s.certs {
if c.Equal(cert) {
return
}
}
 
n := len(s.certs)
s.certs = append(s.certs, cert)
 
if len(cert.SubjectKeyId) > 0 {
keyId := string(cert.SubjectKeyId)
s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], n)
}
name := string(cert.RawSubject)
s.byName[name] = append(s.byName[name], n)
}
 
// AppendCertsFromPEM attempts to parse a series of PEM encoded certificates.
// It appends any certificates found to s and returns true if any certificates
// were successfully parsed.
//
// On many Linux systems, /etc/ssl/cert.pem will contain the system wide set
// of root CAs in a format suitable for this function.
func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}
 
cert, err := ParseCertificate(block.Bytes)
if err != nil {
continue
}
 
s.AddCert(cert)
ok = true
}
 
return
}
 
// Subjects returns a list of the DER-encoded subjects of
// all of the certificates in the pool.
func (s *CertPool) Subjects() (res [][]byte) {
res = make([][]byte, len(s.certs))
for i, c := range s.certs {
res[i] = c.RawSubject
}
return
}
/x509/pkix/pkix.go
0,0 → 1,171
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package pkix contains shared, low level structures used for ASN.1 parsing
// and serialization of X.509 certificates, CRL and OCSP.
package pkix
 
import (
"encoding/asn1"
"math/big"
"time"
)
 
// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
// 5280, section 4.1.1.2.
type AlgorithmIdentifier struct {
Algorithm asn1.ObjectIdentifier
Parameters asn1.RawValue `asn1:"optional"`
}
 
type RDNSequence []RelativeDistinguishedNameSET
 
type RelativeDistinguishedNameSET []AttributeTypeAndValue
 
// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
type AttributeTypeAndValue struct {
Type asn1.ObjectIdentifier
Value interface{}
}
 
// Extension represents the ASN.1 structure of the same name. See RFC
// 5280, section 4.2.
type Extension struct {
Id asn1.ObjectIdentifier
Critical bool `asn1:"optional"`
Value []byte
}
 
// Name represents an X.509 distinguished name. This only includes the common
// elements of a DN. Additional elements in the name are ignored.
type Name struct {
Country, Organization, OrganizationalUnit []string
Locality, Province []string
StreetAddress, PostalCode []string
SerialNumber, CommonName string
 
Names []AttributeTypeAndValue
}
 
func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
for _, rdn := range *rdns {
if len(rdn) == 0 {
continue
}
atv := rdn[0]
n.Names = append(n.Names, atv)
value, ok := atv.Value.(string)
if !ok {
continue
}
 
t := atv.Type
if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
switch t[3] {
case 3:
n.CommonName = value
case 5:
n.SerialNumber = value
case 6:
n.Country = append(n.Country, value)
case 7:
n.Locality = append(n.Locality, value)
case 8:
n.Province = append(n.Province, value)
case 9:
n.StreetAddress = append(n.StreetAddress, value)
case 10:
n.Organization = append(n.Organization, value)
case 11:
n.OrganizationalUnit = append(n.OrganizationalUnit, value)
case 17:
n.PostalCode = append(n.PostalCode, value)
}
}
}
}
 
var (
oidCountry = []int{2, 5, 4, 6}
oidOrganization = []int{2, 5, 4, 10}
oidOrganizationalUnit = []int{2, 5, 4, 11}
oidCommonName = []int{2, 5, 4, 3}
oidSerialNumber = []int{2, 5, 4, 5}
oidLocality = []int{2, 5, 4, 7}
oidProvince = []int{2, 5, 4, 8}
oidStreetAddress = []int{2, 5, 4, 9}
oidPostalCode = []int{2, 5, 4, 17}
)
 
// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
// and returns the new value. The relativeDistinguishedNameSET contains an
// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
// search for AttributeTypeAndValue.
func appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
if len(values) == 0 {
return in
}
 
s := make([]AttributeTypeAndValue, len(values))
for i, value := range values {
s[i].Type = oid
s[i].Value = value
}
 
return append(in, s)
}
 
func (n Name) ToRDNSequence() (ret RDNSequence) {
ret = appendRDNs(ret, n.Country, oidCountry)
ret = appendRDNs(ret, n.Organization, oidOrganization)
ret = appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
ret = appendRDNs(ret, n.Locality, oidLocality)
ret = appendRDNs(ret, n.Province, oidProvince)
ret = appendRDNs(ret, n.StreetAddress, oidStreetAddress)
ret = appendRDNs(ret, n.PostalCode, oidPostalCode)
if len(n.CommonName) > 0 {
ret = appendRDNs(ret, []string{n.CommonName}, oidCommonName)
}
if len(n.SerialNumber) > 0 {
ret = appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
}
 
return ret
}
 
// CertificateList represents the ASN.1 structure of the same name. See RFC
// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
// signature.
type CertificateList struct {
TBSCertList TBSCertificateList
SignatureAlgorithm AlgorithmIdentifier
SignatureValue asn1.BitString
}
 
// HasExpired returns true iff now is past the expiry time of certList.
func (certList *CertificateList) HasExpired(now time.Time) bool {
return now.After(certList.TBSCertList.NextUpdate)
}
 
// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
// 5280, section 5.1.
type TBSCertificateList struct {
Raw asn1.RawContent
Version int `asn1:"optional,default:2"`
Signature AlgorithmIdentifier
Issuer RDNSequence
ThisUpdate time.Time
NextUpdate time.Time
RevokedCertificates []RevokedCertificate `asn1:"optional"`
Extensions []Extension `asn1:"tag:0,optional,explicit"`
}
 
// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
// 5280, section 5.1.
type RevokedCertificate struct {
SerialNumber *big.Int
RevocationTime time.Time
Extensions []Extension `asn1:"optional"`
}
/x509/pkcs8_test.go
0,0 → 1,20
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"encoding/hex"
"testing"
)
 
var pkcs8PrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031`
 
func TestPKCS8(t *testing.T) {
derBytes, _ := hex.DecodeString(pkcs8PrivateKeyHex)
_, err := ParsePKCS8PrivateKey(derBytes)
if err != nil {
t.Errorf("failed to decode PKCS8 key: %s", err)
}
}
/x509/pkcs8.go
0,0 → 1,42
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package x509
 
import (
"crypto/x509/pkix"
"encoding/asn1"
"errors"
"fmt"
)
 
// pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn.
type pkcs8 struct {
Version int
Algo pkix.AlgorithmIdentifier
PrivateKey []byte
// optional attributes omitted.
}
 
// ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. See
// http://www.rsa.com/rsalabs/node.asp?id=2130
func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
var privKey pkcs8
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
return nil, err
}
switch {
case privKey.Algo.Algorithm.Equal(oidRSA):
key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
if err != nil {
return nil, errors.New("crypto/x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
}
return key, nil
default:
return nil, fmt.Errorf("crypto/x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
}
 
panic("unreachable")
}
/elliptic/elliptic_test.go
0,0 → 1,363
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package elliptic
 
import (
"crypto/rand"
"encoding/hex"
"fmt"
"math/big"
"testing"
)
 
func TestOnCurve(t *testing.T) {
p224 := P224()
if !p224.IsOnCurve(p224.Params().Gx, p224.Params().Gy) {
t.Errorf("FAIL")
}
}
 
type baseMultTest struct {
k string
x, y string
}
 
var p224BaseMultTests = []baseMultTest{
{
"1",
"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
},
{
"2",
"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
"1c2b76a7bc25e7702a704fa986892849fca629487acf3709d2e4e8bb",
},
{
"3",
"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
"a3f7f03cadd0be444c0aa56830130ddf77d317344e1af3591981a925",
},
{
"4",
"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
"482580a0ec5bc47e88bc8c378632cd196cb3fa058a7114eb03054c9",
},
{
"5",
"31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa",
"27e8bff1745635ec5ba0c9f1c2ede15414c6507d29ffe37e790a079b",
},
{
"6",
"1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408",
"89faf0ccb750d99b553c574fad7ecfb0438586eb3952af5b4b153c7e",
},
{
"7",
"db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28",
"f3a30085497f2f611ee2517b163ef8c53b715d18bb4e4808d02b963",
},
{
"8",
"858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550",
"46dcd3ea5c43898c5c5fc4fdac7db39c2f02ebee4e3541d1e78047a",
},
{
"9",
"2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d",
"371732e4f41bf4f7883035e6a79fcedc0e196eb07b48171697517463",
},
{
"10",
"aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd",
"39bb30eab337e0a521b6cba1abe4b2b3a3e524c14a3fe3eb116b655f",
},
{
"11",
"ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c",
"20b510004092e96636cfb7e32efded8265c266dfb754fa6d6491a6da",
},
{
"12",
"6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a",
"207dddf0385bfdeab6e9acda8da06b3bbef224a93ab1e9e036109d13",
},
{
"13",
"34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca",
"252819f71c7fb7fbcb159be337d37d3336d7feb963724fdfb0ecb767",
},
{
"14",
"a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa",
"d5814cd724199c4a5b974a43685fbf5b8bac69459c9469bc8f23ccaf",
},
{
"15",
"baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9",
"979a5f4759f80f4fb4ec2e34f5566d595680a11735e7b61046127989",
},
{
"16",
"b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d",
"3399d464345906b11b00e363ef429221f2ec720d2f665d7dead5b482",
},
{
"17",
"b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc",
"ff149efa6606a6bd20ef7d1b06bd92f6904639dce5174db6cc554a26",
},
{
"18",
"c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc",
"ea98d60e5ffc9b8fcf999fab1df7e7ef7084f20ddb61bb045a6ce002",
},
{
"19",
"a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c",
"dcf1f6c3db09c70acc25391d492fe25b4a180babd6cea356c04719cd",
},
{
"20",
"fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455",
"d5d7110274cba7cdee90e1a8b0d394c376a5573db6be0bf2747f530",
},
{
"112233445566778899",
"61f077c6f62ed802dad7c2f38f5c67f2cc453601e61bd076bb46179e",
"2272f9e9f5933e70388ee652513443b5e289dd135dcc0d0299b225e4",
},
{
"112233445566778899112233445566778899",
"29895f0af496bfc62b6ef8d8a65c88c613949b03668aab4f0429e35",
"3ea6e53f9a841f2019ec24bde1a75677aa9b5902e61081c01064de93",
},
{
"6950511619965839450988900688150712778015737983940691968051900319680",
"ab689930bcae4a4aa5f5cb085e823e8ae30fd365eb1da4aba9cf0379",
"3345a121bbd233548af0d210654eb40bab788a03666419be6fbd34e7",
},
{
"13479972933410060327035789020509431695094902435494295338570602119423",
"bdb6a8817c1f89da1c2f3dd8e97feb4494f2ed302a4ce2bc7f5f4025",
"4c7020d57c00411889462d77a5438bb4e97d177700bf7243a07f1680",
},
{
"13479971751745682581351455311314208093898607229429740618390390702079",
"d58b61aa41c32dd5eba462647dba75c5d67c83606c0af2bd928446a9",
"d24ba6a837be0460dd107ae77725696d211446c5609b4595976b16bd",
},
{
"13479972931865328106486971546324465392952975980343228160962702868479",
"dc9fa77978a005510980e929a1485f63716df695d7a0c18bb518df03",
"ede2b016f2ddffc2a8c015b134928275ce09e5661b7ab14ce0d1d403",
},
{
"11795773708834916026404142434151065506931607341523388140225443265536",
"499d8b2829cfb879c901f7d85d357045edab55028824d0f05ba279ba",
"bf929537b06e4015919639d94f57838fa33fc3d952598dcdbb44d638",
},
{
"784254593043826236572847595991346435467177662189391577090",
"8246c999137186632c5f9eddf3b1b0e1764c5e8bd0e0d8a554b9cb77",
"e80ed8660bc1cb17ac7d845be40a7a022d3306f116ae9f81fea65947",
},
{
"13479767645505654746623887797783387853576174193480695826442858012671",
"6670c20afcceaea672c97f75e2e9dd5c8460e54bb38538ebb4bd30eb",
"f280d8008d07a4caf54271f993527d46ff3ff46fd1190a3f1faa4f74",
},
{
"205688069665150753842126177372015544874550518966168735589597183",
"eca934247425cfd949b795cb5ce1eff401550386e28d1a4c5a8eb",
"d4c01040dba19628931bc8855370317c722cbd9ca6156985f1c2e9ce",
},
{
"13479966930919337728895168462090683249159702977113823384618282123295",
"ef353bf5c73cd551b96d596fbc9a67f16d61dd9fe56af19de1fba9cd",
"21771b9cdce3e8430c09b3838be70b48c21e15bc09ee1f2d7945b91f",
},
{
"50210731791415612487756441341851895584393717453129007497216",
"4036052a3091eb481046ad3289c95d3ac905ca0023de2c03ecd451cf",
"d768165a38a2b96f812586a9d59d4136035d9c853a5bf2e1c86a4993",
},
{
"26959946667150639794667015087019625940457807714424391721682722368041",
"fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455",
"f2a28eefd8b345832116f1e574f2c6b2c895aa8c24941f40d8b80ad1",
},
{
"26959946667150639794667015087019625940457807714424391721682722368042",
"a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c",
"230e093c24f638f533dac6e2b6d01da3b5e7f45429315ca93fb8e634",
},
{
"26959946667150639794667015087019625940457807714424391721682722368043",
"c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc",
"156729f1a003647030666054e208180f8f7b0df2249e44fba5931fff",
},
{
"26959946667150639794667015087019625940457807714424391721682722368044",
"b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc",
"eb610599f95942df1082e4f9426d086fb9c6231ae8b24933aab5db",
},
{
"26959946667150639794667015087019625940457807714424391721682722368045",
"b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d",
"cc662b9bcba6f94ee4ff1c9c10bd6ddd0d138df2d099a282152a4b7f",
},
{
"26959946667150639794667015087019625940457807714424391721682722368046",
"baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9",
"6865a0b8a607f0b04b13d1cb0aa992a5a97f5ee8ca1849efb9ed8678",
},
{
"26959946667150639794667015087019625940457807714424391721682722368047",
"a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa",
"2a7eb328dbe663b5a468b5bc97a040a3745396ba636b964370dc3352",
},
{
"26959946667150639794667015087019625940457807714424391721682722368048",
"34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca",
"dad7e608e380480434ea641cc82c82cbc92801469c8db0204f13489a",
},
{
"26959946667150639794667015087019625940457807714424391721682722368049",
"6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a",
"df82220fc7a4021549165325725f94c3410ddb56c54e161fc9ef62ee",
},
{
"26959946667150639794667015087019625940457807714424391721682722368050",
"ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c",
"df4aefffbf6d1699c930481cd102127c9a3d992048ab05929b6e5927",
},
{
"26959946667150639794667015087019625940457807714424391721682722368051",
"aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd",
"c644cf154cc81f5ade49345e541b4d4b5c1adb3eb5c01c14ee949aa2",
},
{
"26959946667150639794667015087019625940457807714424391721682722368052",
"2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d",
"c8e8cd1b0be40b0877cfca1958603122f1e6914f84b7e8e968ae8b9e",
},
{
"26959946667150639794667015087019625940457807714424391721682722368053",
"858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550",
"fb9232c15a3bc7673a3a03b0253824c53d0fd1411b1cabe2e187fb87",
},
{
"26959946667150639794667015087019625940457807714424391721682722368054",
"db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28",
"f0c5cff7ab680d09ee11dae84e9c1072ac48ea2e744b1b7f72fd469e",
},
{
"26959946667150639794667015087019625940457807714424391721682722368055",
"1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408",
"76050f3348af2664aac3a8b05281304ebc7a7914c6ad50a4b4eac383",
},
{
"26959946667150639794667015087019625940457807714424391721682722368056",
"31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa",
"d817400e8ba9ca13a45f360e3d121eaaeb39af82d6001c8186f5f866",
},
{
"26959946667150639794667015087019625940457807714424391721682722368057",
"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
"fb7da7f5f13a43b81774373c879cd32d6934c05fa758eeb14fcfab38",
},
{
"26959946667150639794667015087019625940457807714424391721682722368058",
"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
"5c080fc3522f41bbb3f55a97cfecf21f882ce8cbb1e50ca6e67e56dc",
},
{
"26959946667150639794667015087019625940457807714424391721682722368059",
"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
"e3d4895843da188fd58fb0567976d7b50359d6b78530c8f62d1b1746",
},
{
"26959946667150639794667015087019625940457807714424391721682722368060",
"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
"42c89c774a08dc04b3dd201932bc8a5ea5f8b89bbb2a7e667aff81cd",
},
}
 
func TestBaseMult(t *testing.T) {
p224 := P224()
for i, e := range p224BaseMultTests {
k, ok := new(big.Int).SetString(e.k, 10)
if !ok {
t.Errorf("%d: bad value for k: %s", i, e.k)
}
x, y := p224.ScalarBaseMult(k.Bytes())
if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y {
t.Errorf("%d: bad output for k=%s: got (%x, %x), want (%s, %s)", i, e.k, x, y, e.x, e.y)
}
if testing.Short() && i > 5 {
break
}
}
}
 
func TestGenericBaseMult(t *testing.T) {
// We use the P224 CurveParams directly in order to test the generic implementation.
p224 := P224().Params()
for i, e := range p224BaseMultTests {
k, ok := new(big.Int).SetString(e.k, 10)
if !ok {
t.Errorf("%d: bad value for k: %s", i, e.k)
}
x, y := p224.ScalarBaseMult(k.Bytes())
if fmt.Sprintf("%x", x) != e.x || fmt.Sprintf("%x", y) != e.y {
t.Errorf("%d: bad output for k=%s: got (%x, %x), want (%s, %s)", i, e.k, x, y, e.x, e.y)
}
if testing.Short() && i > 5 {
break
}
}
}
 
func BenchmarkBaseMult(b *testing.B) {
b.ResetTimer()
p224 := P224()
e := p224BaseMultTests[25]
k, _ := new(big.Int).SetString(e.k, 10)
b.StartTimer()
for i := 0; i < b.N; i++ {
p224.ScalarBaseMult(k.Bytes())
}
}
 
func TestMarshal(t *testing.T) {
p224 := P224()
_, x, y, err := GenerateKey(p224, rand.Reader)
if err != nil {
t.Error(err)
return
}
serialized := Marshal(p224, x, y)
xx, yy := Unmarshal(p224, serialized)
if xx == nil {
t.Error("failed to unmarshal")
return
}
if xx.Cmp(x) != 0 || yy.Cmp(y) != 0 {
t.Error("unmarshal returned different values")
return
}
}
 
func TestP224Overflow(t *testing.T) {
// This tests for a specific bug in the P224 implementation.
p224 := P224()
pointData, _ := hex.DecodeString("049B535B45FB0A2072398A6831834624C7E32CCFD5A4B933BCEAF77F1DD945E08BBE5178F5EDF5E733388F196D2A631D2E075BB16CBFEEA15B")
x, y := Unmarshal(p224, pointData)
if !p224.IsOnCurve(x, y) {
t.Error("P224 failed to validate a correct point")
}
}
/elliptic/elliptic.go
0,0 → 1,377
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package elliptic implements several standard elliptic curves over prime
// fields.
package elliptic
 
// This package operates, internally, on Jacobian coordinates. For a given
// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
// calculation can be performed within the transform (as in ScalarMult and
// ScalarBaseMult). But even for Add and Double, it's faster to apply and
// reverse the transform than to operate in affine coordinates.
 
import (
"io"
"math/big"
"sync"
)
 
// A Curve represents a short-form Weierstrass curve with a=-3.
// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
type Curve interface {
// Params returns the parameters for the curve.
Params() *CurveParams
// IsOnCurve returns true if the given (x,y) lies on the curve.
IsOnCurve(x, y *big.Int) bool
// Add returns the sum of (x1,y1) and (x2,y2)
Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
// Double returns 2*(x,y)
Double(x1, y1 *big.Int) (x, y *big.Int)
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int)
// ScalarBaseMult returns k*G, where G is the base point of the group and k
// is an integer in big-endian form.
ScalarBaseMult(scalar []byte) (x, y *big.Int)
}
 
// CurveParams contains the parameters of an elliptic curve and also provides
// a generic, non-constant time implementation of Curve.
type CurveParams struct {
P *big.Int // the order of the underlying field
N *big.Int // the order of the base point
B *big.Int // the constant of the curve equation
Gx, Gy *big.Int // (x,y) of the base point
BitSize int // the size of the underlying field
}
 
func (curve *CurveParams) Params() *CurveParams {
return curve
}
 
func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
// y² = x³ - 3x + b
y2 := new(big.Int).Mul(y, y)
y2.Mod(y2, curve.P)
 
x3 := new(big.Int).Mul(x, x)
x3.Mul(x3, x)
 
threeX := new(big.Int).Lsh(x, 1)
threeX.Add(threeX, x)
 
x3.Sub(x3, threeX)
x3.Add(x3, curve.B)
x3.Mod(x3, curve.P)
 
return x3.Cmp(y2) == 0
}
 
// affineFromJacobian reverses the Jacobian transform. See the comment at the
// top of the file.
func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
zinv := new(big.Int).ModInverse(z, curve.P)
zinvsq := new(big.Int).Mul(zinv, zinv)
 
xOut = new(big.Int).Mul(x, zinvsq)
xOut.Mod(xOut, curve.P)
zinvsq.Mul(zinvsq, zinv)
yOut = new(big.Int).Mul(y, zinvsq)
yOut.Mod(yOut, curve.P)
return
}
 
func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
z := new(big.Int).SetInt64(1)
return curve.affineFromJacobian(curve.addJacobian(x1, y1, z, x2, y2, z))
}
 
// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
// (x2, y2, z2) and returns their sum, also in Jacobian form.
func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
z1z1 := new(big.Int).Mul(z1, z1)
z1z1.Mod(z1z1, curve.P)
z2z2 := new(big.Int).Mul(z2, z2)
z2z2.Mod(z2z2, curve.P)
 
u1 := new(big.Int).Mul(x1, z2z2)
u1.Mod(u1, curve.P)
u2 := new(big.Int).Mul(x2, z1z1)
u2.Mod(u2, curve.P)
h := new(big.Int).Sub(u2, u1)
if h.Sign() == -1 {
h.Add(h, curve.P)
}
i := new(big.Int).Lsh(h, 1)
i.Mul(i, i)
j := new(big.Int).Mul(h, i)
 
s1 := new(big.Int).Mul(y1, z2)
s1.Mul(s1, z2z2)
s1.Mod(s1, curve.P)
s2 := new(big.Int).Mul(y2, z1)
s2.Mul(s2, z1z1)
s2.Mod(s2, curve.P)
r := new(big.Int).Sub(s2, s1)
if r.Sign() == -1 {
r.Add(r, curve.P)
}
r.Lsh(r, 1)
v := new(big.Int).Mul(u1, i)
 
x3 := new(big.Int).Set(r)
x3.Mul(x3, x3)
x3.Sub(x3, j)
x3.Sub(x3, v)
x3.Sub(x3, v)
x3.Mod(x3, curve.P)
 
y3 := new(big.Int).Set(r)
v.Sub(v, x3)
y3.Mul(y3, v)
s1.Mul(s1, j)
s1.Lsh(s1, 1)
y3.Sub(y3, s1)
y3.Mod(y3, curve.P)
 
z3 := new(big.Int).Add(z1, z2)
z3.Mul(z3, z3)
z3.Sub(z3, z1z1)
if z3.Sign() == -1 {
z3.Add(z3, curve.P)
}
z3.Sub(z3, z2z2)
if z3.Sign() == -1 {
z3.Add(z3, curve.P)
}
z3.Mul(z3, h)
z3.Mod(z3, curve.P)
 
return x3, y3, z3
}
 
func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
z1 := new(big.Int).SetInt64(1)
return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
}
 
// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
// returns its double, also in Jacobian form.
func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
delta := new(big.Int).Mul(z, z)
delta.Mod(delta, curve.P)
gamma := new(big.Int).Mul(y, y)
gamma.Mod(gamma, curve.P)
alpha := new(big.Int).Sub(x, delta)
if alpha.Sign() == -1 {
alpha.Add(alpha, curve.P)
}
alpha2 := new(big.Int).Add(x, delta)
alpha.Mul(alpha, alpha2)
alpha2.Set(alpha)
alpha.Lsh(alpha, 1)
alpha.Add(alpha, alpha2)
 
beta := alpha2.Mul(x, gamma)
 
x3 := new(big.Int).Mul(alpha, alpha)
beta8 := new(big.Int).Lsh(beta, 3)
x3.Sub(x3, beta8)
for x3.Sign() == -1 {
x3.Add(x3, curve.P)
}
x3.Mod(x3, curve.P)
 
z3 := new(big.Int).Add(y, z)
z3.Mul(z3, z3)
z3.Sub(z3, gamma)
if z3.Sign() == -1 {
z3.Add(z3, curve.P)
}
z3.Sub(z3, delta)
if z3.Sign() == -1 {
z3.Add(z3, curve.P)
}
z3.Mod(z3, curve.P)
 
beta.Lsh(beta, 2)
beta.Sub(beta, x3)
if beta.Sign() == -1 {
beta.Add(beta, curve.P)
}
y3 := alpha.Mul(alpha, beta)
 
gamma.Mul(gamma, gamma)
gamma.Lsh(gamma, 3)
gamma.Mod(gamma, curve.P)
 
y3.Sub(y3, gamma)
if y3.Sign() == -1 {
y3.Add(y3, curve.P)
}
y3.Mod(y3, curve.P)
 
return x3, y3, z3
}
 
func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
// We have a slight problem in that the identity of the group (the
// point at infinity) cannot be represented in (x, y) form on a finite
// machine. Thus the standard add/double algorithm has to be tweaked
// slightly: our initial state is not the identity, but x, and we
// ignore the first true bit in |k|. If we don't find any true bits in
// |k|, then we return nil, nil, because we cannot return the identity
// element.
 
Bz := new(big.Int).SetInt64(1)
x := Bx
y := By
z := Bz
 
seenFirstTrue := false
for _, byte := range k {
for bitNum := 0; bitNum < 8; bitNum++ {
if seenFirstTrue {
x, y, z = curve.doubleJacobian(x, y, z)
}
if byte&0x80 == 0x80 {
if !seenFirstTrue {
seenFirstTrue = true
} else {
x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
}
}
byte <<= 1
}
}
 
if !seenFirstTrue {
return nil, nil
}
 
return curve.affineFromJacobian(x, y, z)
}
 
func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
return curve.ScalarMult(curve.Gx, curve.Gy, k)
}
 
var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
 
// GenerateKey returns a public/private key pair. The private key is
// generated using the given reader, which must return random data.
func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
bitSize := curve.Params().BitSize
byteLen := (bitSize + 7) >> 3
priv = make([]byte, byteLen)
 
for x == nil {
_, err = io.ReadFull(rand, priv)
if err != nil {
return
}
// We have to mask off any excess bits in the case that the size of the
// underlying field is not a whole number of bytes.
priv[0] &= mask[bitSize%8]
// This is because, in tests, rand will return all zeros and we don't
// want to get the point at infinity and loop forever.
priv[1] ^= 0x42
x, y = curve.ScalarBaseMult(priv)
}
return
}
 
// Marshal converts a point into the form specified in section 4.3.6 of ANSI X9.62.
func Marshal(curve Curve, x, y *big.Int) []byte {
byteLen := (curve.Params().BitSize + 7) >> 3
 
ret := make([]byte, 1+2*byteLen)
ret[0] = 4 // uncompressed point
 
xBytes := x.Bytes()
copy(ret[1+byteLen-len(xBytes):], xBytes)
yBytes := y.Bytes()
copy(ret[1+2*byteLen-len(yBytes):], yBytes)
return ret
}
 
// Unmarshal converts a point, serialized by Marshal, into an x, y pair. On error, x = nil.
func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
byteLen := (curve.Params().BitSize + 7) >> 3
if len(data) != 1+2*byteLen {
return
}
if data[0] != 4 { // uncompressed form
return
}
x = new(big.Int).SetBytes(data[1 : 1+byteLen])
y = new(big.Int).SetBytes(data[1+byteLen:])
return
}
 
var initonce sync.Once
var p256 *CurveParams
var p384 *CurveParams
var p521 *CurveParams
 
func initAll() {
initP224()
initP256()
initP384()
initP521()
}
 
func initP256() {
// See FIPS 186-3, section D.2.3
p256 = new(CurveParams)
p256.P, _ = new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10)
p256.N, _ = new(big.Int).SetString("115792089210356248762697446949407573529996955224135760342422259061068512044369", 10)
p256.B, _ = new(big.Int).SetString("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)
p256.Gx, _ = new(big.Int).SetString("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16)
p256.Gy, _ = new(big.Int).SetString("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16)
p256.BitSize = 256
}
 
func initP384() {
// See FIPS 186-3, section D.2.4
p384 = new(CurveParams)
p384.P, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319", 10)
p384.N, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10)
p384.B, _ = new(big.Int).SetString("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16)
p384.Gx, _ = new(big.Int).SetString("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16)
p384.Gy, _ = new(big.Int).SetString("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16)
p384.BitSize = 384
}
 
func initP521() {
// See FIPS 186-3, section D.2.5
p521 = new(CurveParams)
p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16)
p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16)
p521.BitSize = 521
}
 
// P256 returns a Curve which implements P-256 (see FIPS 186-3, section D.2.3)
func P256() Curve {
initonce.Do(initAll)
return p256
}
 
// P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4)
func P384() Curve {
initonce.Do(initAll)
return p384
}
 
// P256 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
func P521() Curve {
initonce.Do(initAll)
return p521
}
/elliptic/p224_test.go
0,0 → 1,47
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package elliptic
 
import (
"math/big"
"testing"
)
 
var toFromBigTests = []string{
"0",
"1",
"23",
"b70e0cb46bb4bf7f321390b94a03c1d356c01122343280d6105c1d21",
"706a46d476dcb76798e6046d89474788d164c18032d268fd10704fa6",
}
 
func p224AlternativeToBig(in *p224FieldElement) *big.Int {
ret := new(big.Int)
tmp := new(big.Int)
 
for i := uint(0); i < 8; i++ {
tmp.SetInt64(int64(in[i]))
tmp.Lsh(tmp, 28*i)
ret.Add(ret, tmp)
}
ret.Mod(ret, p224.P)
return ret
}
 
func TestToFromBig(t *testing.T) {
for i, test := range toFromBigTests {
n, _ := new(big.Int).SetString(test, 16)
var x p224FieldElement
p224FromBig(&x, n)
m := p224ToBig(&x)
if n.Cmp(m) != 0 {
t.Errorf("#%d: %x != %x", i, n, m)
}
q := p224AlternativeToBig(&x)
if n.Cmp(q) != 0 {
t.Errorf("#%d: %x != %x (alternative)", i, n, m)
}
}
}
/elliptic/p224.go
0,0 → 1,718
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package elliptic
 
// This is a constant-time, 32-bit implementation of P224. See FIPS 186-3,
// section D.2.2.
//
// See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background.
 
import (
"math/big"
)
 
var p224 p224Curve
 
type p224Curve struct {
*CurveParams
gx, gy, b p224FieldElement
}
 
func initP224() {
// See FIPS 186-3, section D.2.2
p224.CurveParams = new(CurveParams)
p224.P, _ = new(big.Int).SetString("26959946667150639794667015087019630673557916260026308143510066298881", 10)
p224.N, _ = new(big.Int).SetString("26959946667150639794667015087019625940457807714424391721682722368061", 10)
p224.B, _ = new(big.Int).SetString("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", 16)
p224.Gx, _ = new(big.Int).SetString("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", 16)
p224.Gy, _ = new(big.Int).SetString("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", 16)
p224.BitSize = 224
 
p224FromBig(&p224.gx, p224.Gx)
p224FromBig(&p224.gy, p224.Gy)
p224FromBig(&p224.b, p224.B)
}
 
// P224 returns a Curve which implements P-224 (see FIPS 186-3, section D.2.2)
func P224() Curve {
initonce.Do(initAll)
return p224
}
 
func (curve p224Curve) Params() *CurveParams {
return curve.CurveParams
}
 
func (curve p224Curve) IsOnCurve(bigX, bigY *big.Int) bool {
var x, y p224FieldElement
p224FromBig(&x, bigX)
p224FromBig(&y, bigY)
 
// y² = x³ - 3x + b
var tmp p224LargeFieldElement
var x3 p224FieldElement
p224Square(&x3, &x, &tmp)
p224Mul(&x3, &x3, &x, &tmp)
 
for i := 0; i < 8; i++ {
x[i] *= 3
}
p224Sub(&x3, &x3, &x)
p224Reduce(&x3)
p224Add(&x3, &x3, &curve.b)
p224Contract(&x3, &x3)
 
p224Square(&y, &y, &tmp)
p224Contract(&y, &y)
 
for i := 0; i < 8; i++ {
if y[i] != x3[i] {
return false
}
}
return true
}
 
func (p224Curve) Add(bigX1, bigY1, bigX2, bigY2 *big.Int) (x, y *big.Int) {
var x1, y1, z1, x2, y2, z2, x3, y3, z3 p224FieldElement
 
p224FromBig(&x1, bigX1)
p224FromBig(&y1, bigY1)
z1[0] = 1
p224FromBig(&x2, bigX2)
p224FromBig(&y2, bigY2)
z2[0] = 1
 
p224AddJacobian(&x3, &y3, &z3, &x1, &y1, &z1, &x2, &y2, &z2)
return p224ToAffine(&x3, &y3, &z3)
}
 
func (p224Curve) Double(bigX1, bigY1 *big.Int) (x, y *big.Int) {
var x1, y1, z1, x2, y2, z2 p224FieldElement
 
p224FromBig(&x1, bigX1)
p224FromBig(&y1, bigY1)
z1[0] = 1
 
p224DoubleJacobian(&x2, &y2, &z2, &x1, &y1, &z1)
return p224ToAffine(&x2, &y2, &z2)
}
 
func (p224Curve) ScalarMult(bigX1, bigY1 *big.Int, scalar []byte) (x, y *big.Int) {
var x1, y1, z1, x2, y2, z2 p224FieldElement
 
p224FromBig(&x1, bigX1)
p224FromBig(&y1, bigY1)
z1[0] = 1
 
p224ScalarMult(&x2, &y2, &z2, &x1, &y1, &z1, scalar)
return p224ToAffine(&x2, &y2, &z2)
}
 
func (curve p224Curve) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
var z1, x2, y2, z2 p224FieldElement
 
z1[0] = 1
p224ScalarMult(&x2, &y2, &z2, &curve.gx, &curve.gy, &z1, scalar)
return p224ToAffine(&x2, &y2, &z2)
}
 
// Field element functions.
//
// The field that we're dealing with is ℤ/pℤ where p = 2**224 - 2**96 + 1.
//
// Field elements are represented by a FieldElement, which is a typedef to an
// array of 8 uint32's. The value of a FieldElement, a, is:
// a[0] + 2**28·a[1] + 2**56·a[1] + ... + 2**196·a[7]
//
// Using 28-bit limbs means that there's only 4 bits of headroom, which is less
// than we would really like. But it has the useful feature that we hit 2**224
// exactly, making the reflections during a reduce much nicer.
type p224FieldElement [8]uint32
 
// p224Add computes *out = a+b
//
// a[i] + b[i] < 2**32
func p224Add(out, a, b *p224FieldElement) {
for i := 0; i < 8; i++ {
out[i] = a[i] + b[i]
}
}
 
const two31p3 = 1<<31 + 1<<3
const two31m3 = 1<<31 - 1<<3
const two31m15m3 = 1<<31 - 1<<15 - 1<<3
 
// p224ZeroModP31 is 0 mod p where bit 31 is set in all limbs so that we can
// subtract smaller amounts without underflow. See the section "Subtraction" in
// [1] for reasoning.
var p224ZeroModP31 = []uint32{two31p3, two31m3, two31m3, two31m15m3, two31m3, two31m3, two31m3, two31m3}
 
// p224Sub computes *out = a-b
//
// a[i], b[i] < 2**30
// out[i] < 2**32
func p224Sub(out, a, b *p224FieldElement) {
for i := 0; i < 8; i++ {
out[i] = a[i] + p224ZeroModP31[i] - b[i]
}
}
 
// LargeFieldElement also represents an element of the field. The limbs are
// still spaced 28-bits apart and in little-endian order. So the limbs are at
// 0, 28, 56, ..., 392 bits, each 64-bits wide.
type p224LargeFieldElement [15]uint64
 
const two63p35 = 1<<63 + 1<<35
const two63m35 = 1<<63 - 1<<35
const two63m35m19 = 1<<63 - 1<<35 - 1<<19
 
// p224ZeroModP63 is 0 mod p where bit 63 is set in all limbs. See the section
// "Subtraction" in [1] for why.
var p224ZeroModP63 = [8]uint64{two63p35, two63m35, two63m35, two63m35, two63m35m19, two63m35, two63m35, two63m35}
 
const bottom12Bits = 0xfff
const bottom28Bits = 0xfffffff
 
// p224Mul computes *out = a*b
//
// a[i] < 2**29, b[i] < 2**30 (or vice versa)
// out[i] < 2**29
func p224Mul(out, a, b *p224FieldElement, tmp *p224LargeFieldElement) {
for i := 0; i < 15; i++ {
tmp[i] = 0
}
 
for i := 0; i < 8; i++ {
for j := 0; j < 8; j++ {
tmp[i+j] += uint64(a[i]) * uint64(b[j])
}
}
 
p224ReduceLarge(out, tmp)
}
 
// Square computes *out = a*a
//
// a[i] < 2**29
// out[i] < 2**29
func p224Square(out, a *p224FieldElement, tmp *p224LargeFieldElement) {
for i := 0; i < 15; i++ {
tmp[i] = 0
}
 
for i := 0; i < 8; i++ {
for j := 0; j <= i; j++ {
r := uint64(a[i]) * uint64(a[j])
if i == j {
tmp[i+j] += r
} else {
tmp[i+j] += r << 1
}
}
}
 
p224ReduceLarge(out, tmp)
}
 
// ReduceLarge converts a p224LargeFieldElement to a p224FieldElement.
//
// in[i] < 2**62
func p224ReduceLarge(out *p224FieldElement, in *p224LargeFieldElement) {
for i := 0; i < 8; i++ {
in[i] += p224ZeroModP63[i]
}
 
// Eliminate the coefficients at 2**224 and greater.
for i := 14; i >= 8; i-- {
in[i-8] -= in[i]
in[i-5] += (in[i] & 0xffff) << 12
in[i-4] += in[i] >> 16
}
in[8] = 0
// in[0..8] < 2**64
 
// As the values become small enough, we start to store them in |out|
// and use 32-bit operations.
for i := 1; i < 8; i++ {
in[i+1] += in[i] >> 28
out[i] = uint32(in[i] & bottom28Bits)
}
in[0] -= in[8]
out[3] += uint32(in[8]&0xffff) << 12
out[4] += uint32(in[8] >> 16)
// in[0] < 2**64
// out[3] < 2**29
// out[4] < 2**29
// out[1,2,5..7] < 2**28
 
out[0] = uint32(in[0] & bottom28Bits)
out[1] += uint32((in[0] >> 28) & bottom28Bits)
out[2] += uint32(in[0] >> 56)
// out[0] < 2**28
// out[1..4] < 2**29
// out[5..7] < 2**28
}
 
// Reduce reduces the coefficients of a to smaller bounds.
//
// On entry: a[i] < 2**31 + 2**30
// On exit: a[i] < 2**29
func p224Reduce(a *p224FieldElement) {
for i := 0; i < 7; i++ {
a[i+1] += a[i] >> 28
a[i] &= bottom28Bits
}
top := a[7] >> 28
a[7] &= bottom28Bits
 
// top < 2**4
mask := top
mask |= mask >> 2
mask |= mask >> 1
mask <<= 31
mask = uint32(int32(mask) >> 31)
// Mask is all ones if top != 0, all zero otherwise
 
a[0] -= top
a[3] += top << 12
 
// We may have just made a[0] negative but, if we did, then we must
// have added something to a[3], this it's > 2**12. Therefore we can
// carry down to a[0].
a[3] -= 1 & mask
a[2] += mask & (1<<28 - 1)
a[1] += mask & (1<<28 - 1)
a[0] += mask & (1 << 28)
}
 
// p224Invert calculates *out = in**-1 by computing in**(2**224 - 2**96 - 1),
// i.e. Fermat's little theorem.
func p224Invert(out, in *p224FieldElement) {
var f1, f2, f3, f4 p224FieldElement
var c p224LargeFieldElement
 
p224Square(&f1, in, &c) // 2
p224Mul(&f1, &f1, in, &c) // 2**2 - 1
p224Square(&f1, &f1, &c) // 2**3 - 2
p224Mul(&f1, &f1, in, &c) // 2**3 - 1
p224Square(&f2, &f1, &c) // 2**4 - 2
p224Square(&f2, &f2, &c) // 2**5 - 4
p224Square(&f2, &f2, &c) // 2**6 - 8
p224Mul(&f1, &f1, &f2, &c) // 2**6 - 1
p224Square(&f2, &f1, &c) // 2**7 - 2
for i := 0; i < 5; i++ { // 2**12 - 2**6
p224Square(&f2, &f2, &c)
}
p224Mul(&f2, &f2, &f1, &c) // 2**12 - 1
p224Square(&f3, &f2, &c) // 2**13 - 2
for i := 0; i < 11; i++ { // 2**24 - 2**12
p224Square(&f3, &f3, &c)
}
p224Mul(&f2, &f3, &f2, &c) // 2**24 - 1
p224Square(&f3, &f2, &c) // 2**25 - 2
for i := 0; i < 23; i++ { // 2**48 - 2**24
p224Square(&f3, &f3, &c)
}
p224Mul(&f3, &f3, &f2, &c) // 2**48 - 1
p224Square(&f4, &f3, &c) // 2**49 - 2
for i := 0; i < 47; i++ { // 2**96 - 2**48
p224Square(&f4, &f4, &c)
}
p224Mul(&f3, &f3, &f4, &c) // 2**96 - 1
p224Square(&f4, &f3, &c) // 2**97 - 2
for i := 0; i < 23; i++ { // 2**120 - 2**24
p224Square(&f4, &f4, &c)
}
p224Mul(&f2, &f4, &f2, &c) // 2**120 - 1
for i := 0; i < 6; i++ { // 2**126 - 2**6
p224Square(&f2, &f2, &c)
}
p224Mul(&f1, &f1, &f2, &c) // 2**126 - 1
p224Square(&f1, &f1, &c) // 2**127 - 2
p224Mul(&f1, &f1, in, &c) // 2**127 - 1
for i := 0; i < 97; i++ { // 2**224 - 2**97
p224Square(&f1, &f1, &c)
}
p224Mul(out, &f1, &f3, &c) // 2**224 - 2**96 - 1
}
 
// p224Contract converts a FieldElement to its unique, minimal form.
//
// On entry, in[i] < 2**29
// On exit, in[i] < 2**28
func p224Contract(out, in *p224FieldElement) {
copy(out[:], in[:])
 
for i := 0; i < 7; i++ {
out[i+1] += out[i] >> 28
out[i] &= bottom28Bits
}
top := out[7] >> 28
out[7] &= bottom28Bits
 
out[0] -= top
out[3] += top << 12
 
// We may just have made out[i] negative. So we carry down. If we made
// out[0] negative then we know that out[3] is sufficiently positive
// because we just added to it.
for i := 0; i < 3; i++ {
mask := uint32(int32(out[i]) >> 31)
out[i] += (1 << 28) & mask
out[i+1] -= 1 & mask
}
 
// We might have pushed out[3] over 2**28 so we perform another, partial,
// carry chain.
for i := 3; i < 7; i++ {
out[i+1] += out[i] >> 28
out[i] &= bottom28Bits
}
top = out[7] >> 28
out[7] &= bottom28Bits
 
// Eliminate top while maintaining the same value mod p.
out[0] -= top
out[3] += top << 12
 
// There are two cases to consider for out[3]:
// 1) The first time that we eliminated top, we didn't push out[3] over
// 2**28. In this case, the partial carry chain didn't change any values
// and top is zero.
// 2) We did push out[3] over 2**28 the first time that we eliminated top.
// The first value of top was in [0..16), therefore, prior to eliminating
// the first top, 0xfff1000 <= out[3] <= 0xfffffff. Therefore, after
// overflowing and being reduced by the second carry chain, out[3] <=
// 0xf000. Thus it cannot have overflowed when we eliminated top for the
// second time.
 
// Again, we may just have made out[0] negative, so do the same carry down.
// As before, if we made out[0] negative then we know that out[3] is
// sufficiently positive.
for i := 0; i < 3; i++ {
mask := uint32(int32(out[i]) >> 31)
out[i] += (1 << 28) & mask
out[i+1] -= 1 & mask
}
 
// Now we see if the value is >= p and, if so, subtract p.
 
// First we build a mask from the top four limbs, which must all be
// equal to bottom28Bits if the whole value is >= p. If top4AllOnes
// ends up with any zero bits in the bottom 28 bits, then this wasn't
// true.
top4AllOnes := uint32(0xffffffff)
for i := 4; i < 8; i++ {
top4AllOnes &= (out[i] & bottom28Bits) - 1
}
top4AllOnes |= 0xf0000000
// Now we replicate any zero bits to all the bits in top4AllOnes.
top4AllOnes &= top4AllOnes >> 16
top4AllOnes &= top4AllOnes >> 8
top4AllOnes &= top4AllOnes >> 4
top4AllOnes &= top4AllOnes >> 2
top4AllOnes &= top4AllOnes >> 1
top4AllOnes = uint32(int32(top4AllOnes<<31) >> 31)
 
// Now we test whether the bottom three limbs are non-zero.
bottom3NonZero := out[0] | out[1] | out[2]
bottom3NonZero |= bottom3NonZero >> 16
bottom3NonZero |= bottom3NonZero >> 8
bottom3NonZero |= bottom3NonZero >> 4
bottom3NonZero |= bottom3NonZero >> 2
bottom3NonZero |= bottom3NonZero >> 1
bottom3NonZero = uint32(int32(bottom3NonZero<<31) >> 31)
 
// Everything depends on the value of out[3].
// If it's > 0xffff000 and top4AllOnes != 0 then the whole value is >= p
// If it's = 0xffff000 and top4AllOnes != 0 and bottom3NonZero != 0,
// then the whole value is >= p
// If it's < 0xffff000, then the whole value is < p
n := out[3] - 0xffff000
out3Equal := n
out3Equal |= out3Equal >> 16
out3Equal |= out3Equal >> 8
out3Equal |= out3Equal >> 4
out3Equal |= out3Equal >> 2
out3Equal |= out3Equal >> 1
out3Equal = ^uint32(int32(out3Equal<<31) >> 31)
 
// If out[3] > 0xffff000 then n's MSB will be zero.
out3GT := ^uint32(int32(n<<31) >> 31)
 
mask := top4AllOnes & ((out3Equal & bottom3NonZero) | out3GT)
out[0] -= 1 & mask
out[3] -= 0xffff000 & mask
out[4] -= 0xfffffff & mask
out[5] -= 0xfffffff & mask
out[6] -= 0xfffffff & mask
out[7] -= 0xfffffff & mask
}
 
// Group element functions.
//
// These functions deal with group elements. The group is an elliptic curve
// group with a = -3 defined in FIPS 186-3, section D.2.2.
 
// p224AddJacobian computes *out = a+b where a != b.
func p224AddJacobian(x3, y3, z3, x1, y1, z1, x2, y2, z2 *p224FieldElement) {
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-p224Add-2007-bl
var z1z1, z2z2, u1, u2, s1, s2, h, i, j, r, v p224FieldElement
var c p224LargeFieldElement
 
// Z1Z1 = Z1²
p224Square(&z1z1, z1, &c)
// Z2Z2 = Z2²
p224Square(&z2z2, z2, &c)
// U1 = X1*Z2Z2
p224Mul(&u1, x1, &z2z2, &c)
// U2 = X2*Z1Z1
p224Mul(&u2, x2, &z1z1, &c)
// S1 = Y1*Z2*Z2Z2
p224Mul(&s1, z2, &z2z2, &c)
p224Mul(&s1, y1, &s1, &c)
// S2 = Y2*Z1*Z1Z1
p224Mul(&s2, z1, &z1z1, &c)
p224Mul(&s2, y2, &s2, &c)
// H = U2-U1
p224Sub(&h, &u2, &u1)
p224Reduce(&h)
// I = (2*H)²
for j := 0; j < 8; j++ {
i[j] = h[j] << 1
}
p224Reduce(&i)
p224Square(&i, &i, &c)
// J = H*I
p224Mul(&j, &h, &i, &c)
// r = 2*(S2-S1)
p224Sub(&r, &s2, &s1)
p224Reduce(&r)
for i := 0; i < 8; i++ {
r[i] <<= 1
}
p224Reduce(&r)
// V = U1*I
p224Mul(&v, &u1, &i, &c)
// Z3 = ((Z1+Z2)²-Z1Z1-Z2Z2)*H
p224Add(&z1z1, &z1z1, &z2z2)
p224Add(&z2z2, z1, z2)
p224Reduce(&z2z2)
p224Square(&z2z2, &z2z2, &c)
p224Sub(z3, &z2z2, &z1z1)
p224Reduce(z3)
p224Mul(z3, z3, &h, &c)
// X3 = r²-J-2*V
for i := 0; i < 8; i++ {
z1z1[i] = v[i] << 1
}
p224Add(&z1z1, &j, &z1z1)
p224Reduce(&z1z1)
p224Square(x3, &r, &c)
p224Sub(x3, x3, &z1z1)
p224Reduce(x3)
// Y3 = r*(V-X3)-2*S1*J
for i := 0; i < 8; i++ {
s1[i] <<= 1
}
p224Mul(&s1, &s1, &j, &c)
p224Sub(&z1z1, &v, x3)
p224Reduce(&z1z1)
p224Mul(&z1z1, &z1z1, &r, &c)
p224Sub(y3, &z1z1, &s1)
p224Reduce(y3)
}
 
// p224DoubleJacobian computes *out = a+a.
func p224DoubleJacobian(x3, y3, z3, x1, y1, z1 *p224FieldElement) {
var delta, gamma, beta, alpha, t p224FieldElement
var c p224LargeFieldElement
 
p224Square(&delta, z1, &c)
p224Square(&gamma, y1, &c)
p224Mul(&beta, x1, &gamma, &c)
 
// alpha = 3*(X1-delta)*(X1+delta)
p224Add(&t, x1, &delta)
for i := 0; i < 8; i++ {
t[i] += t[i] << 1
}
p224Reduce(&t)
p224Sub(&alpha, x1, &delta)
p224Reduce(&alpha)
p224Mul(&alpha, &alpha, &t, &c)
 
// Z3 = (Y1+Z1)²-gamma-delta
p224Add(z3, y1, z1)
p224Reduce(z3)
p224Square(z3, z3, &c)
p224Sub(z3, z3, &gamma)
p224Reduce(z3)
p224Sub(z3, z3, &delta)
p224Reduce(z3)
 
// X3 = alpha²-8*beta
for i := 0; i < 8; i++ {
delta[i] = beta[i] << 3
}
p224Reduce(&delta)
p224Square(x3, &alpha, &c)
p224Sub(x3, x3, &delta)
p224Reduce(x3)
 
// Y3 = alpha*(4*beta-X3)-8*gamma²
for i := 0; i < 8; i++ {
beta[i] <<= 2
}
p224Sub(&beta, &beta, x3)
p224Reduce(&beta)
p224Square(&gamma, &gamma, &c)
for i := 0; i < 8; i++ {
gamma[i] <<= 3
}
p224Reduce(&gamma)
p224Mul(y3, &alpha, &beta, &c)
p224Sub(y3, y3, &gamma)
p224Reduce(y3)
}
 
// p224CopyConditional sets *out = *in iff the least-significant-bit of control
// is true, and it runs in constant time.
func p224CopyConditional(out, in *p224FieldElement, control uint32) {
control <<= 31
control = uint32(int32(control) >> 31)
 
for i := 0; i < 8; i++ {
out[i] ^= (out[i] ^ in[i]) & control
}
}
 
func p224ScalarMult(outX, outY, outZ, inX, inY, inZ *p224FieldElement, scalar []byte) {
var xx, yy, zz p224FieldElement
for i := 0; i < 8; i++ {
outZ[i] = 0
}
 
firstBit := uint32(1)
for _, byte := range scalar {
for bitNum := uint(0); bitNum < 8; bitNum++ {
p224DoubleJacobian(outX, outY, outZ, outX, outY, outZ)
bit := uint32((byte >> (7 - bitNum)) & 1)
p224AddJacobian(&xx, &yy, &zz, inX, inY, inZ, outX, outY, outZ)
p224CopyConditional(outX, inX, firstBit&bit)
p224CopyConditional(outY, inY, firstBit&bit)
p224CopyConditional(outZ, inZ, firstBit&bit)
p224CopyConditional(outX, &xx, ^firstBit&bit)
p224CopyConditional(outY, &yy, ^firstBit&bit)
p224CopyConditional(outZ, &zz, ^firstBit&bit)
firstBit = firstBit & ^bit
}
}
}
 
// p224ToAffine converts from Jacobian to affine form.
func p224ToAffine(x, y, z *p224FieldElement) (*big.Int, *big.Int) {
var zinv, zinvsq, outx, outy p224FieldElement
var tmp p224LargeFieldElement
 
isPointAtInfinity := true
for i := 0; i < 8; i++ {
if z[i] != 0 {
isPointAtInfinity = false
break
}
}
 
if isPointAtInfinity {
return nil, nil
}
 
p224Invert(&zinv, z)
p224Square(&zinvsq, &zinv, &tmp)
p224Mul(x, x, &zinvsq, &tmp)
p224Mul(&zinvsq, &zinvsq, &zinv, &tmp)
p224Mul(y, y, &zinvsq, &tmp)
 
p224Contract(&outx, x)
p224Contract(&outy, y)
return p224ToBig(&outx), p224ToBig(&outy)
}
 
// get28BitsFromEnd returns the least-significant 28 bits from buf>>shift,
// where buf is interpreted as a big-endian number.
func get28BitsFromEnd(buf []byte, shift uint) (uint32, []byte) {
var ret uint32
 
for i := uint(0); i < 4; i++ {
var b byte
if l := len(buf); l > 0 {
b = buf[l-1]
// We don't remove the byte if we're about to return and we're not
// reading all of it.
if i != 3 || shift == 4 {
buf = buf[:l-1]
}
}
ret |= uint32(b) << (8 * i) >> shift
}
ret &= bottom28Bits
return ret, buf
}
 
// p224FromBig sets *out = *in.
func p224FromBig(out *p224FieldElement, in *big.Int) {
bytes := in.Bytes()
out[0], bytes = get28BitsFromEnd(bytes, 0)
out[1], bytes = get28BitsFromEnd(bytes, 4)
out[2], bytes = get28BitsFromEnd(bytes, 0)
out[3], bytes = get28BitsFromEnd(bytes, 4)
out[4], bytes = get28BitsFromEnd(bytes, 0)
out[5], bytes = get28BitsFromEnd(bytes, 4)
out[6], bytes = get28BitsFromEnd(bytes, 0)
out[7], bytes = get28BitsFromEnd(bytes, 4)
}
 
// p224ToBig returns in as a big.Int.
func p224ToBig(in *p224FieldElement) *big.Int {
var buf [28]byte
buf[27] = byte(in[0])
buf[26] = byte(in[0] >> 8)
buf[25] = byte(in[0] >> 16)
buf[24] = byte(((in[0] >> 24) & 0x0f) | (in[1]<<4)&0xf0)
 
buf[23] = byte(in[1] >> 4)
buf[22] = byte(in[1] >> 12)
buf[21] = byte(in[1] >> 20)
 
buf[20] = byte(in[2])
buf[19] = byte(in[2] >> 8)
buf[18] = byte(in[2] >> 16)
buf[17] = byte(((in[2] >> 24) & 0x0f) | (in[3]<<4)&0xf0)
 
buf[16] = byte(in[3] >> 4)
buf[15] = byte(in[3] >> 12)
buf[14] = byte(in[3] >> 20)
 
buf[13] = byte(in[4])
buf[12] = byte(in[4] >> 8)
buf[11] = byte(in[4] >> 16)
buf[10] = byte(((in[4] >> 24) & 0x0f) | (in[5]<<4)&0xf0)
 
buf[9] = byte(in[5] >> 4)
buf[8] = byte(in[5] >> 12)
buf[7] = byte(in[5] >> 20)
 
buf[6] = byte(in[6])
buf[5] = byte(in[6] >> 8)
buf[4] = byte(in[6] >> 16)
buf[3] = byte(((in[6] >> 24) & 0x0f) | (in[7]<<4)&0xf0)
 
buf[2] = byte(in[7] >> 4)
buf[1] = byte(in[7] >> 12)
buf[0] = byte(in[7] >> 20)
 
return new(big.Int).SetBytes(buf[:])
}
/dsa/dsa_test.go
0,0 → 1,84
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package dsa
 
import (
"crypto/rand"
"math/big"
"testing"
)
 
func testSignAndVerify(t *testing.T, i int, priv *PrivateKey) {
hashed := []byte("testing")
r, s, err := Sign(rand.Reader, priv, hashed)
if err != nil {
t.Errorf("%d: error signing: %s", i, err)
return
}
 
if !Verify(&priv.PublicKey, hashed, r, s) {
t.Errorf("%d: Verify failed", i)
}
}
 
func testParameterGeneration(t *testing.T, sizes ParameterSizes, L, N int) {
var priv PrivateKey
params := &priv.Parameters
 
err := GenerateParameters(params, rand.Reader, sizes)
if err != nil {
t.Errorf("%d: %s", int(sizes), err)
return
}
 
if params.P.BitLen() != L {
t.Errorf("%d: params.BitLen got:%d want:%d", int(sizes), params.P.BitLen(), L)
}
 
if params.Q.BitLen() != N {
t.Errorf("%d: q.BitLen got:%d want:%d", int(sizes), params.Q.BitLen(), L)
}
 
one := new(big.Int)
one.SetInt64(1)
pm1 := new(big.Int).Sub(params.P, one)
quo, rem := new(big.Int).DivMod(pm1, params.Q, new(big.Int))
if rem.Sign() != 0 {
t.Errorf("%d: p-1 mod q != 0", int(sizes))
}
x := new(big.Int).Exp(params.G, quo, params.P)
if x.Cmp(one) == 0 {
t.Errorf("%d: invalid generator", int(sizes))
}
 
err = GenerateKey(&priv, rand.Reader)
if err != nil {
t.Errorf("error generating key: %s", err)
return
}
 
testSignAndVerify(t, int(sizes), &priv)
}
 
func TestParameterGeneration(t *testing.T) {
// This test is too slow to run all the time.
return
 
testParameterGeneration(t, L1024N160, 1024, 160)
testParameterGeneration(t, L2048N224, 2048, 224)
testParameterGeneration(t, L2048N256, 2048, 256)
testParameterGeneration(t, L3072N256, 3072, 256)
}
 
func TestSignAndVerify(t *testing.T) {
var priv PrivateKey
priv.P, _ = new(big.Int).SetString("A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF", 16)
priv.Q, _ = new(big.Int).SetString("E1D3391245933D68A0714ED34BBCB7A1F422B9C1", 16)
priv.G, _ = new(big.Int).SetString("634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA", 16)
priv.Y, _ = new(big.Int).SetString("32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2", 16)
priv.X, _ = new(big.Int).SetString("5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A", 16)
 
testSignAndVerify(t, 0, &priv)
}
/dsa/dsa.go
0,0 → 1,276
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3
package dsa
 
import (
"errors"
"io"
"math/big"
)
 
// Parameters represents the domain parameters for a key. These parameters can
// be shared across many keys. The bit length of Q must be a multiple of 8.
type Parameters struct {
P, Q, G *big.Int
}
 
// PublicKey represents a DSA public key.
type PublicKey struct {
Parameters
Y *big.Int
}
 
// PrivateKey represents a DSA private key.
type PrivateKey struct {
PublicKey
X *big.Int
}
 
type invalidPublicKeyError int
 
func (invalidPublicKeyError) Error() string {
return "crypto/dsa: invalid public key"
}
 
// ErrInvalidPublicKey results when a public key is not usable by this code.
// FIPS is quite strict about the format of DSA keys, but other code may be
// less so. Thus, when using keys which may have been generated by other code,
// this error must be handled.
var ErrInvalidPublicKey error = invalidPublicKeyError(0)
 
// ParameterSizes is a enumeration of the acceptable bit lengths of the primes
// in a set of DSA parameters. See FIPS 186-3, section 4.2.
type ParameterSizes int
 
const (
L1024N160 ParameterSizes = iota
L2048N224
L2048N256
L3072N256
)
 
// numMRTests is the number of Miller-Rabin primality tests that we perform. We
// pick the largest recommended number from table C.1 of FIPS 186-3.
const numMRTests = 64
 
// GenerateParameters puts a random, valid set of DSA parameters into params.
// This function takes many seconds, even on fast machines.
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err error) {
// This function doesn't follow FIPS 186-3 exactly in that it doesn't
// use a verification seed to generate the primes. The verification
// seed doesn't appear to be exported or used by other code and
// omitting it makes the code cleaner.
 
var L, N int
switch sizes {
case L1024N160:
L = 1024
N = 160
case L2048N224:
L = 2048
N = 224
case L2048N256:
L = 2048
N = 256
case L3072N256:
L = 3072
N = 256
default:
return errors.New("crypto/dsa: invalid ParameterSizes")
}
 
qBytes := make([]byte, N/8)
pBytes := make([]byte, L/8)
 
q := new(big.Int)
p := new(big.Int)
rem := new(big.Int)
one := new(big.Int)
one.SetInt64(1)
 
GeneratePrimes:
for {
_, err = io.ReadFull(rand, qBytes)
if err != nil {
return
}
 
qBytes[len(qBytes)-1] |= 1
qBytes[0] |= 0x80
q.SetBytes(qBytes)
 
if !q.ProbablyPrime(numMRTests) {
continue
}
 
for i := 0; i < 4*L; i++ {
_, err = io.ReadFull(rand, pBytes)
if err != nil {
return
}
 
pBytes[len(pBytes)-1] |= 1
pBytes[0] |= 0x80
 
p.SetBytes(pBytes)
rem.Mod(p, q)
rem.Sub(rem, one)
p.Sub(p, rem)
if p.BitLen() < L {
continue
}
 
if !p.ProbablyPrime(numMRTests) {
continue
}
 
params.P = p
params.Q = q
break GeneratePrimes
}
}
 
h := new(big.Int)
h.SetInt64(2)
g := new(big.Int)
 
pm1 := new(big.Int).Sub(p, one)
e := new(big.Int).Div(pm1, q)
 
for {
g.Exp(h, e, p)
if g.Cmp(one) == 0 {
h.Add(h, one)
continue
}
 
params.G = g
return
}
 
panic("unreachable")
}
 
// GenerateKey generates a public&private key pair. The Parameters of the
// PrivateKey must already be valid (see GenerateParameters).
func GenerateKey(priv *PrivateKey, rand io.Reader) error {
if priv.P == nil || priv.Q == nil || priv.G == nil {
return errors.New("crypto/dsa: parameters not set up before generating key")
}
 
x := new(big.Int)
xBytes := make([]byte, priv.Q.BitLen()/8)
 
for {
_, err := io.ReadFull(rand, xBytes)
if err != nil {
return err
}
x.SetBytes(xBytes)
if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
break
}
}
 
priv.X = x
priv.Y = new(big.Int)
priv.Y.Exp(priv.G, x, priv.P)
return nil
}
 
// Sign signs an arbitrary length hash (which should be the result of hashing a
// larger message) using the private key, priv. It returns the signature as a
// pair of integers. The security of the private key depends on the entropy of
// rand.
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
// FIPS 186-3, section 4.6
 
n := priv.Q.BitLen()
if n&7 != 0 {
err = ErrInvalidPublicKey
return
}
n >>= 3
 
for {
k := new(big.Int)
buf := make([]byte, n)
for {
_, err = io.ReadFull(rand, buf)
if err != nil {
return
}
k.SetBytes(buf)
if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
break
}
}
 
kInv := new(big.Int).ModInverse(k, priv.Q)
 
r = new(big.Int).Exp(priv.G, k, priv.P)
r.Mod(r, priv.Q)
 
if r.Sign() == 0 {
continue
}
 
z := k.SetBytes(hash)
 
s = new(big.Int).Mul(priv.X, r)
s.Add(s, z)
s.Mod(s, priv.Q)
s.Mul(s, kInv)
s.Mod(s, priv.Q)
 
if s.Sign() != 0 {
break
}
}
 
return
}
 
// Verify verifies the signature in r, s of hash using the public key, pub. It
// reports whether the signature is valid.
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
// FIPS 186-3, section 4.7
 
if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
return false
}
if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
return false
}
 
w := new(big.Int).ModInverse(s, pub.Q)
 
n := pub.Q.BitLen()
if n&7 != 0 {
return false
}
z := new(big.Int).SetBytes(hash)
 
u1 := new(big.Int).Mul(z, w)
u1.Mod(u1, pub.Q)
u2 := w.Mul(r, w)
u2.Mod(u2, pub.Q)
v := u1.Exp(pub.G, u1, pub.P)
u2.Exp(pub.Y, u2, pub.P)
v.Mul(v, u2)
v.Mod(v, pub.P)
v.Mod(v, pub.Q)
 
return v.Cmp(r) == 0
}
/aes/const.go
0,0 → 1,358
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package aes implements AES encryption (formerly Rijndael), as defined in
// U.S. Federal Information Processing Standards Publication 197.
package aes
 
// This file contains AES constants - 8720 bytes of initialized data.
 
// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
 
// AES is based on the mathematical behavior of binary polynomials
// (polynomials over GF(2)) modulo the irreducible polynomial x⁸ + x⁴ + x² + x + 1.
// Addition of these binary polynomials corresponds to binary xor.
// Reducing mod poly corresponds to binary xor with poly every
// time a 0x100 bit appears.
const poly = 1<<8 | 1<<4 | 1<<3 | 1<<1 | 1<<0 // x⁸ + x⁴ + x² + x + 1
 
// Powers of x mod poly in GF(2).
var powx = [16]byte{
0x01,
0x02,
0x04,
0x08,
0x10,
0x20,
0x40,
0x80,
0x1b,
0x36,
0x6c,
0xd8,
0xab,
0x4d,
0x9a,
0x2f,
}
 
// FIPS-197 Figure 7. S-box substitution values in hexadecimal format.
var sbox0 = [256]byte{
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
}
 
// FIPS-197 Figure 14. Inverse S-box substitution values in hexadecimal format.
var sbox1 = [256]byte{
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
}
 
// Lookup tables for encryption.
// These can be recomputed by adapting the tests in aes_test.go.
 
var te0 = [256]uint32{
0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
}
var te1 = [256]uint32{
0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
}
var te2 = [256]uint32{
0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
}
var te3 = [256]uint32{
0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
}
 
// Lookup tables for decryption.
// These can be recomputed by adapting the tests in aes_test.go.
 
var td0 = [256]uint32{
0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
}
var td1 = [256]uint32{
0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
}
var td2 = [256]uint32{
0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
}
var td3 = [256]uint32{
0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
}
/aes/aes_test.go
0,0 → 1,366
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package aes
 
import (
"testing"
)
 
// See const.go for overview of math here.
 
// Test that powx is initialized correctly.
// (Can adapt this code to generate it too.)
func TestPowx(t *testing.T) {
p := 1
for i := 0; i < len(powx); i++ {
if powx[i] != byte(p) {
t.Errorf("powx[%d] = %#x, want %#x", i, powx[i], p)
}
p <<= 1
if p&0x100 != 0 {
p ^= poly
}
}
}
 
// Multiply b and c as GF(2) polynomials modulo poly
func mul(b, c uint32) uint32 {
i := b
j := c
s := uint32(0)
for k := uint32(1); k < 0x100 && j != 0; k <<= 1 {
// Invariant: k == 1<<n, i == b * xⁿ
 
if j&k != 0 {
// s += i in GF(2); xor in binary
s ^= i
j ^= k // turn off bit to end loop early
}
 
// i *= x in GF(2) modulo the polynomial
i <<= 1
if i&0x100 != 0 {
i ^= poly
}
}
return s
}
 
// Test all mul inputs against bit-by-bit n² algorithm.
func TestMul(t *testing.T) {
for i := uint32(0); i < 256; i++ {
for j := uint32(0); j < 256; j++ {
// Multiply i, j bit by bit.
s := uint8(0)
for k := uint(0); k < 8; k++ {
for l := uint(0); l < 8; l++ {
if i&(1<<k) != 0 && j&(1<<l) != 0 {
s ^= powx[k+l]
}
}
}
if x := mul(i, j); x != uint32(s) {
t.Fatalf("mul(%#x, %#x) = %#x, want %#x", i, j, x, s)
}
}
}
}
 
// Check that S-boxes are inverses of each other.
// They have more structure that we could test,
// but if this sanity check passes, we'll assume
// the cut and paste from the FIPS PDF worked.
func TestSboxes(t *testing.T) {
for i := 0; i < 256; i++ {
if j := sbox0[sbox1[i]]; j != byte(i) {
t.Errorf("sbox0[sbox1[%#x]] = %#x", i, j)
}
if j := sbox1[sbox0[i]]; j != byte(i) {
t.Errorf("sbox1[sbox0[%#x]] = %#x", i, j)
}
}
}
 
// Test that encryption tables are correct.
// (Can adapt this code to generate them too.)
func TestTe(t *testing.T) {
for i := 0; i < 256; i++ {
s := uint32(sbox0[i])
s2 := mul(s, 2)
s3 := mul(s, 3)
w := s2<<24 | s<<16 | s<<8 | s3
te := [][256]uint32{te0, te1, te2, te3}
for j := 0; j < 4; j++ {
if x := te[j][i]; x != w {
t.Fatalf("te[%d][%d] = %#x, want %#x", j, i, x, w)
}
w = w<<24 | w>>8
}
}
}
 
// Test that decryption tables are correct.
// (Can adapt this code to generate them too.)
func TestTd(t *testing.T) {
for i := 0; i < 256; i++ {
s := uint32(sbox1[i])
s9 := mul(s, 0x9)
sb := mul(s, 0xb)
sd := mul(s, 0xd)
se := mul(s, 0xe)
w := se<<24 | s9<<16 | sd<<8 | sb
td := [][256]uint32{td0, td1, td2, td3}
for j := 0; j < 4; j++ {
if x := td[j][i]; x != w {
t.Fatalf("td[%d][%d] = %#x, want %#x", j, i, x, w)
}
w = w<<24 | w>>8
}
}
}
 
// Test vectors are from FIPS 197:
// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
 
// Appendix A of FIPS 197: Key expansion examples
type KeyTest struct {
key []byte
enc []uint32
dec []uint32 // decryption expansion; not in FIPS 197, computed from C implementation.
}
 
var keyTests = []KeyTest{
{
// A.1. Expansion of a 128-bit Cipher Key
[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
[]uint32{
0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c,
0xa0fafe17, 0x88542cb1, 0x23a33939, 0x2a6c7605,
0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f,
0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b,
0xef44a541, 0xa8525b7f, 0xb671253b, 0xdb0bad00,
0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc,
0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd,
0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f,
0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f,
0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e,
0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6,
},
[]uint32{
0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6,
0xc7b5a63, 0x1319eafe, 0xb0398890, 0x664cfbb4,
0xdf7d925a, 0x1f62b09d, 0xa320626e, 0xd6757324,
0x12c07647, 0xc01f22c7, 0xbc42d2f3, 0x7555114a,
0x6efcd876, 0xd2df5480, 0x7c5df034, 0xc917c3b9,
0x6ea30afc, 0xbc238cf6, 0xae82a4b4, 0xb54a338d,
0x90884413, 0xd280860a, 0x12a12842, 0x1bc89739,
0x7c1f13f7, 0x4208c219, 0xc021ae48, 0x969bf7b,
0xcc7505eb, 0x3e17d1ee, 0x82296c51, 0xc9481133,
0x2b3708a7, 0xf262d405, 0xbc3ebdbf, 0x4b617d62,
0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x9cf4f3c,
},
},
{
// A.2. Expansion of a 192-bit Cipher Key
[]byte{
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
},
[]uint32{
0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5,
0x62f8ead2, 0x522c6b7b, 0xfe0c91f7, 0x2402f5a5,
0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2,
0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd,
0xe75fad44, 0xbb095386, 0x485af057, 0x21efb14f,
0xa448f6d9, 0x4d6dce24, 0xaa326360, 0x113b30e6,
0xa25e7ed5, 0x83b1cf9a, 0x27f93943, 0x6a94f767,
0xc0a69407, 0xd19da4e1, 0xec1786eb, 0x6fa64971,
0x485f7032, 0x22cb8755, 0xe26d1352, 0x33f0b7b3,
0x40beeb28, 0x2f18a259, 0x6747d26b, 0x458c553e,
0xa7e1466c, 0x9411f1df, 0x821f750a, 0xad07d753,
0xca400538, 0x8fcc5006, 0x282d166a, 0xbc3ce7b5,
0xe98ba06f, 0x448c773c, 0x8ecc7204, 0x01002202,
},
nil,
},
{
// A.3. Expansion of a 256-bit Cipher Key
[]byte{
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
},
[]uint32{
0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781,
0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4,
0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde,
0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a,
0xd59aecb8, 0x5bf3c917, 0xfee94248, 0xde8ebe96,
0xb5a9328a, 0x2678a647, 0x98312229, 0x2f6c79b3,
0x812c81ad, 0xdadf48ba, 0x24360af2, 0xfab8b464,
0x98c5bfc9, 0xbebd198e, 0x268c3ba7, 0x09e04214,
0x68007bac, 0xb2df3316, 0x96e939e4, 0x6c518d80,
0xc814e204, 0x76a9fb8a, 0x5025c02d, 0x59c58239,
0xde136967, 0x6ccc5a71, 0xfa256395, 0x9674ee15,
0x5886ca5d, 0x2e2f31d7, 0x7e0af1fa, 0x27cf73c3,
0x749c47ab, 0x18501dda, 0xe2757e4f, 0x7401905a,
0xcafaaae3, 0xe4d59b34, 0x9adf6ace, 0xbd10190d,
0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e,
},
nil,
},
}
 
// Test key expansion against FIPS 197 examples.
func TestExpandKey(t *testing.T) {
L:
for i, tt := range keyTests {
enc := make([]uint32, len(tt.enc))
var dec []uint32
if tt.dec != nil {
dec = make([]uint32, len(tt.dec))
}
expandKey(tt.key, enc, dec)
for j, v := range enc {
if v != tt.enc[j] {
t.Errorf("key %d: enc[%d] = %#x, want %#x", i, j, v, tt.enc[j])
continue L
}
}
if dec != nil {
for j, v := range dec {
if v != tt.dec[j] {
t.Errorf("key %d: dec[%d] = %#x, want %#x", i, j, v, tt.dec[j])
continue L
}
}
}
}
}
 
// Appendix B, C of FIPS 197: Cipher examples, Example vectors.
type CryptTest struct {
key []byte
in []byte
out []byte
}
 
var encryptTests = []CryptTest{
{
// Appendix B.
[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
[]byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34},
[]byte{0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32},
},
{
// Appendix C.1. AES-128
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
[]byte{0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a},
},
{
// Appendix C.2. AES-192
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
},
[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
[]byte{0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91},
},
{
// Appendix C.3. AES-256
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
},
[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
[]byte{0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89},
},
}
 
// Test encryptBlock against FIPS 197 examples.
func TestEncryptBlock(t *testing.T) {
for i, tt := range encryptTests {
n := len(tt.key) + 28
enc := make([]uint32, n)
dec := make([]uint32, n)
expandKey(tt.key, enc, dec)
out := make([]byte, len(tt.in))
encryptBlock(enc, out, tt.in)
for j, v := range out {
if v != tt.out[j] {
t.Errorf("encryptBlock %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
break
}
}
}
}
 
// Test decryptBlock against FIPS 197 examples.
func TestDecryptBlock(t *testing.T) {
for i, tt := range encryptTests {
n := len(tt.key) + 28
enc := make([]uint32, n)
dec := make([]uint32, n)
expandKey(tt.key, enc, dec)
plain := make([]byte, len(tt.in))
decryptBlock(dec, plain, tt.out)
for j, v := range plain {
if v != tt.in[j] {
t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
break
}
}
}
}
 
// Test Cipher Encrypt method against FIPS 197 examples.
func TestCipherEncrypt(t *testing.T) {
for i, tt := range encryptTests {
c, err := NewCipher(tt.key)
if err != nil {
t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
continue
}
out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in)
for j, v := range out {
if v != tt.out[j] {
t.Errorf("Cipher.Encrypt %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
break
}
}
}
}
 
// Test Cipher Decrypt against FIPS 197 examples.
func TestCipherDecrypt(t *testing.T) {
for i, tt := range encryptTests {
c, err := NewCipher(tt.key)
if err != nil {
t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
continue
}
plain := make([]byte, len(tt.in))
c.Decrypt(plain, tt.out)
for j, v := range plain {
if v != tt.in[j] {
t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
break
}
}
}
}
 
func BenchmarkEncrypt(b *testing.B) {
b.StopTimer()
tt := encryptTests[0]
c, err := NewCipher(tt.key)
if err != nil {
b.Fatal("NewCipher:", err)
}
out := make([]byte, len(tt.in))
b.StartTimer()
for i := 0; i < b.N; i++ {
c.Encrypt(out, tt.in)
}
}
/aes/cipher.go
0,0 → 1,68
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package aes
 
import "strconv"
 
// The AES block size in bytes.
const BlockSize = 16
 
// A Cipher is an instance of AES encryption using a particular key.
type Cipher struct {
enc []uint32
dec []uint32
}
 
type KeySizeError int
 
func (k KeySizeError) Error() string {
return "crypto/aes: invalid key size " + strconv.Itoa(int(k))
}
 
// NewCipher creates and returns a new Cipher.
// The key argument should be the AES key,
// either 16, 24, or 32 bytes to select
// AES-128, AES-192, or AES-256.
func NewCipher(key []byte) (*Cipher, error) {
k := len(key)
switch k {
default:
return nil, KeySizeError(k)
case 16, 24, 32:
break
}
 
n := k + 28
c := &Cipher{make([]uint32, n), make([]uint32, n)}
expandKey(key, c.enc, c.dec)
return c, nil
}
 
// BlockSize returns the AES block size, 16 bytes.
// It is necessary to satisfy the Block interface in the
// package "crypto/cipher".
func (c *Cipher) BlockSize() int { return BlockSize }
 
// Encrypt encrypts the 16-byte buffer src using the key k
// and stores the result in dst.
// Note that for amounts of data larger than a block,
// it is not safe to just call Encrypt on successive blocks;
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.enc, dst, src) }
 
// Decrypt decrypts the 16-byte buffer src using the key k
// and stores the result in dst.
func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.dec, dst, src) }
 
// Reset zeros the key data, so that it will no longer
// appear in the process's memory.
func (c *Cipher) Reset() {
for i := 0; i < len(c.enc); i++ {
c.enc[i] = 0
}
for i := 0; i < len(c.dec); i++ {
c.dec[i] = 0
}
}
/aes/block.go
0,0 → 1,176
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// This Go implementation is derived in part from the reference
// ANSI C implementation, which carries the following notice:
//
// rijndael-alg-fst.c
//
// @version 3.0 (December 2000)
//
// Optimised ANSI C code for the Rijndael cipher (now AES)
//
// @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
// @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
// @author Paulo Barreto <paulo.barreto@terra.com.br>
//
// This code is hereby placed in the public domain.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// See FIPS 197 for specification, and see Daemen and Rijmen's Rijndael submission
// for implementation details.
// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
// http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf
 
package aes
 
// Encrypt one block from src into dst, using the expanded key xk.
func encryptBlock(xk []uint32, dst, src []byte) {
var s0, s1, s2, s3, t0, t1, t2, t3 uint32
 
s0 = uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
s1 = uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
s2 = uint32(src[8])<<24 | uint32(src[9])<<16 | uint32(src[10])<<8 | uint32(src[11])
s3 = uint32(src[12])<<24 | uint32(src[13])<<16 | uint32(src[14])<<8 | uint32(src[15])
 
// First round just XORs input with key.
s0 ^= xk[0]
s1 ^= xk[1]
s2 ^= xk[2]
s3 ^= xk[3]
 
// Middle rounds shuffle using tables.
// Number of rounds is set by length of expanded key.
nr := len(xk)/4 - 2 // - 2: one above, one more below
k := 4
for r := 0; r < nr; r++ {
t0 = xk[k+0] ^ te0[uint8(s0>>24)] ^ te1[uint8(s1>>16)] ^ te2[uint8(s2>>8)] ^ te3[uint8(s3)]
t1 = xk[k+1] ^ te0[uint8(s1>>24)] ^ te1[uint8(s2>>16)] ^ te2[uint8(s3>>8)] ^ te3[uint8(s0)]
t2 = xk[k+2] ^ te0[uint8(s2>>24)] ^ te1[uint8(s3>>16)] ^ te2[uint8(s0>>8)] ^ te3[uint8(s1)]
t3 = xk[k+3] ^ te0[uint8(s3>>24)] ^ te1[uint8(s0>>16)] ^ te2[uint8(s1>>8)] ^ te3[uint8(s2)]
k += 4
s0, s1, s2, s3 = t0, t1, t2, t3
}
 
// Last round uses s-box directly and XORs to produce output.
s0 = uint32(sbox0[t0>>24])<<24 | uint32(sbox0[t1>>16&0xff])<<16 | uint32(sbox0[t2>>8&0xff])<<8 | uint32(sbox0[t3&0xff])
s1 = uint32(sbox0[t1>>24])<<24 | uint32(sbox0[t2>>16&0xff])<<16 | uint32(sbox0[t3>>8&0xff])<<8 | uint32(sbox0[t0&0xff])
s2 = uint32(sbox0[t2>>24])<<24 | uint32(sbox0[t3>>16&0xff])<<16 | uint32(sbox0[t0>>8&0xff])<<8 | uint32(sbox0[t1&0xff])
s3 = uint32(sbox0[t3>>24])<<24 | uint32(sbox0[t0>>16&0xff])<<16 | uint32(sbox0[t1>>8&0xff])<<8 | uint32(sbox0[t2&0xff])
 
s0 ^= xk[k+0]
s1 ^= xk[k+1]
s2 ^= xk[k+2]
s3 ^= xk[k+3]
 
dst[0], dst[1], dst[2], dst[3] = byte(s0>>24), byte(s0>>16), byte(s0>>8), byte(s0)
dst[4], dst[5], dst[6], dst[7] = byte(s1>>24), byte(s1>>16), byte(s1>>8), byte(s1)
dst[8], dst[9], dst[10], dst[11] = byte(s2>>24), byte(s2>>16), byte(s2>>8), byte(s2)
dst[12], dst[13], dst[14], dst[15] = byte(s3>>24), byte(s3>>16), byte(s3>>8), byte(s3)
}
 
// Decrypt one block from src into dst, using the expanded key xk.
func decryptBlock(xk []uint32, dst, src []byte) {
var s0, s1, s2, s3, t0, t1, t2, t3 uint32
 
s0 = uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
s1 = uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
s2 = uint32(src[8])<<24 | uint32(src[9])<<16 | uint32(src[10])<<8 | uint32(src[11])
s3 = uint32(src[12])<<24 | uint32(src[13])<<16 | uint32(src[14])<<8 | uint32(src[15])
 
// First round just XORs input with key.
s0 ^= xk[0]
s1 ^= xk[1]
s2 ^= xk[2]
s3 ^= xk[3]
 
// Middle rounds shuffle using tables.
// Number of rounds is set by length of expanded key.
nr := len(xk)/4 - 2 // - 2: one above, one more below
k := 4
for r := 0; r < nr; r++ {
t0 = xk[k+0] ^ td0[uint8(s0>>24)] ^ td1[uint8(s3>>16)] ^ td2[uint8(s2>>8)] ^ td3[uint8(s1)]
t1 = xk[k+1] ^ td0[uint8(s1>>24)] ^ td1[uint8(s0>>16)] ^ td2[uint8(s3>>8)] ^ td3[uint8(s2)]
t2 = xk[k+2] ^ td0[uint8(s2>>24)] ^ td1[uint8(s1>>16)] ^ td2[uint8(s0>>8)] ^ td3[uint8(s3)]
t3 = xk[k+3] ^ td0[uint8(s3>>24)] ^ td1[uint8(s2>>16)] ^ td2[uint8(s1>>8)] ^ td3[uint8(s0)]
k += 4
s0, s1, s2, s3 = t0, t1, t2, t3
}
 
// Last round uses s-box directly and XORs to produce output.
s0 = uint32(sbox1[t0>>24])<<24 | uint32(sbox1[t3>>16&0xff])<<16 | uint32(sbox1[t2>>8&0xff])<<8 | uint32(sbox1[t1&0xff])
s1 = uint32(sbox1[t1>>24])<<24 | uint32(sbox1[t0>>16&0xff])<<16 | uint32(sbox1[t3>>8&0xff])<<8 | uint32(sbox1[t2&0xff])
s2 = uint32(sbox1[t2>>24])<<24 | uint32(sbox1[t1>>16&0xff])<<16 | uint32(sbox1[t0>>8&0xff])<<8 | uint32(sbox1[t3&0xff])
s3 = uint32(sbox1[t3>>24])<<24 | uint32(sbox1[t2>>16&0xff])<<16 | uint32(sbox1[t1>>8&0xff])<<8 | uint32(sbox1[t0&0xff])
 
s0 ^= xk[k+0]
s1 ^= xk[k+1]
s2 ^= xk[k+2]
s3 ^= xk[k+3]
 
dst[0], dst[1], dst[2], dst[3] = byte(s0>>24), byte(s0>>16), byte(s0>>8), byte(s0)
dst[4], dst[5], dst[6], dst[7] = byte(s1>>24), byte(s1>>16), byte(s1>>8), byte(s1)
dst[8], dst[9], dst[10], dst[11] = byte(s2>>24), byte(s2>>16), byte(s2>>8), byte(s2)
dst[12], dst[13], dst[14], dst[15] = byte(s3>>24), byte(s3>>16), byte(s3>>8), byte(s3)
}
 
// Apply sbox0 to each byte in w.
func subw(w uint32) uint32 {
return uint32(sbox0[w>>24])<<24 |
uint32(sbox0[w>>16&0xff])<<16 |
uint32(sbox0[w>>8&0xff])<<8 |
uint32(sbox0[w&0xff])
}
 
// Rotate
func rotw(w uint32) uint32 { return w<<8 | w>>24 }
 
// Key expansion algorithm. See FIPS-197, Figure 11.
// Their rcon[i] is our powx[i-1] << 24.
func expandKey(key []byte, enc, dec []uint32) {
// Encryption key setup.
var i int
nk := len(key) / 4
for i = 0; i < nk; i++ {
enc[i] = uint32(key[4*i])<<24 | uint32(key[4*i+1])<<16 | uint32(key[4*i+2])<<8 | uint32(key[4*i+3])
}
for ; i < len(enc); i++ {
t := enc[i-1]
if i%nk == 0 {
t = subw(rotw(t)) ^ (uint32(powx[i/nk-1]) << 24)
} else if nk > 6 && i%nk == 4 {
t = subw(t)
}
enc[i] = enc[i-nk] ^ t
}
 
// Derive decryption key from encryption key.
// Reverse the 4-word round key sets from enc to produce dec.
// All sets but the first and last get the MixColumn transform applied.
if dec == nil {
return
}
n := len(enc)
for i := 0; i < n; i += 4 {
ei := n - i - 4
for j := 0; j < 4; j++ {
x := enc[ei+j]
if i > 0 && i+4 < n {
x = td0[sbox0[x>>24]] ^ td1[sbox0[x>>16&0xff]] ^ td2[sbox0[x>>8&0xff]] ^ td3[sbox0[x&0xff]]
}
dec[i+j] = x
}
}
}
/hmac/hmac_test.go
0,0 → 1,493
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package hmac
 
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"fmt"
"hash"
"testing"
)
 
type hmacTest struct {
hash func() hash.Hash
key []byte
in []byte
out string
}
 
var hmacTests = []hmacTest{
// Tests from US FIPS 198
// http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
{
sha1.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
},
[]byte("Sample #1"),
"4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a",
},
{
sha1.New,
[]byte{
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43,
},
[]byte("Sample #2"),
"0922d3405faa3d194f82a45830737d5cc6c75d24",
},
{
sha1.New,
[]byte{
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3,
},
[]byte("Sample #3"),
"bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa",
},
 
// Test from Plan 9.
{
md5.New,
[]byte("Jefe"),
[]byte("what do ya want for nothing?"),
"750c783e6ab0b503eaa86e310a5db738",
},
 
// Tests from RFC 4231
{
sha256.New,
[]byte{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b,
},
[]byte("Hi There"),
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
},
{
sha256.New,
[]byte("Jefe"),
[]byte("what do ya want for nothing?"),
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
},
{
sha256.New,
[]byte{
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa,
},
[]byte{
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd,
},
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
},
{
sha256.New,
[]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19,
},
[]byte{
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd,
},
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
},
{
sha256.New,
[]byte{
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa,
},
[]byte("Test Using Larger Than Block-Size Key - Hash Key First"),
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
},
{
sha256.New,
[]byte{
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa,
},
[]byte("This is a test using a larger than block-size key " +
"and a larger than block-size data. The key needs to " +
"be hashed before being used by the HMAC algorithm."),
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
},
 
// Tests from http://csrc.nist.gov/groups/ST/toolkit/examples.html
// (truncated tag tests are left out)
{
sha1.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
},
[]byte("Sample message for keylen=blocklen"),
"5fd596ee78d5553c8ff4e72d266dfd192366da29",
},
{
sha1.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13,
},
[]byte("Sample message for keylen<blocklen"),
"4c99ff0cb1b31bd33f8431dbaf4d17fcd356a807",
},
{
sha1.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63,
},
[]byte("Sample message for keylen=blocklen"),
"2d51b2f7750e410584662e38f133435f4c4fd42a",
},
{
sha256.New224,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
},
[]byte("Sample message for keylen=blocklen"),
"c7405e3ae058e8cd30b08b4140248581ed174cb34e1224bcc1efc81b",
},
{
sha256.New224,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b,
},
[]byte("Sample message for keylen<blocklen"),
"e3d249a8cfb67ef8b7a169e9a0a599714a2cecba65999a51beb8fbbe",
},
{
sha256.New224,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63,
},
[]byte("Sample message for keylen=blocklen"),
"91c52509e5af8531601ae6230099d90bef88aaefb961f4080abc014d",
},
{
sha256.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
},
[]byte("Sample message for keylen=blocklen"),
"8bb9a1db9806f20df7f77b82138c7914d174d59e13dc4d0169c9057b133e1d62",
},
{
sha256.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
},
[]byte("Sample message for keylen<blocklen"),
"a28cf43130ee696a98f14a37678b56bcfcbdd9e5cf69717fecf5480f0ebdf790",
},
{
sha256.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63,
},
[]byte("Sample message for keylen=blocklen"),
"bdccb6c72ddeadb500ae768386cb38cc41c63dbb0878ddb9c7a38a431b78378d",
},
{
sha512.New384,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
},
[]byte("Sample message for keylen=blocklen"),
"63c5daa5e651847ca897c95814ab830bededc7d25e83eef9195cd45857a37f448947858f5af50cc2b1b730ddf29671a9",
},
{
sha512.New384,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
},
[]byte("Sample message for keylen<blocklen"),
"6eb242bdbb582ca17bebfa481b1e23211464d2b7f8c20b9ff2201637b93646af5ae9ac316e98db45d9cae773675eeed0",
},
{
sha512.New384,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
},
[]byte("Sample message for keylen=blocklen"),
"5b664436df69b0ca22551231a3f0a3d5b4f97991713cfa84bff4d0792eff96c27dccbbb6f79b65d548b40e8564cef594",
},
{
sha512.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
},
[]byte("Sample message for keylen=blocklen"),
"fc25e240658ca785b7a811a8d3f7b4ca" +
"48cfa26a8a366bf2cd1f836b05fcb024bd36853081811d6c" +
"ea4216ebad79da1cfcb95ea4586b8a0ce356596a55fb1347",
},
{
sha512.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
},
[]byte("Sample message for keylen<blocklen"),
"fd44c18bda0bb0a6ce0e82b031bf2818" +
"f6539bd56ec00bdc10a8a2d730b3634de2545d639b0f2cf7" +
"10d0692c72a1896f1f211c2b922d1a96c392e07e7ea9fedc",
},
{
sha512.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
},
[]byte("Sample message for keylen=blocklen"),
"d93ec8d2de1ad2a9957cb9b83f14e76a" +
"d6b5e0cce285079a127d3b14bccb7aa7286d4ac0d4ce6421" +
"5f2bc9e6870b33d97438be4aaa20cda5c5a912b48b8e27f3",
},
}
 
func TestHMAC(t *testing.T) {
for i, tt := range hmacTests {
h := New(tt.hash, tt.key)
for j := 0; j < 2; j++ {
n, err := h.Write(tt.in)
if n != len(tt.in) || err != nil {
t.Errorf("test %d.%d: Write(%d) = %d, %v", i, j, len(tt.in), n, err)
continue
}
 
// Repetitive Sum() calls should return the same value
for k := 0; k < 2; k++ {
sum := fmt.Sprintf("%x", h.Sum(nil))
if sum != tt.out {
t.Errorf("test %d.%d.%d: have %s want %s\n", i, j, k, sum, tt.out)
}
}
 
// Second iteration: make sure reset works.
h.Reset()
}
}
}
/hmac/hmac.go
0,0 → 1,80
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as
// defined in U.S. Federal Information Processing Standards Publication 198.
// An HMAC is a cryptographic hash that uses a key to sign a message.
// The receiver verifies the hash by recomputing it using the same key.
package hmac
 
import (
"hash"
)
 
// FIPS 198:
// http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
 
// key is zero padded to the block size of the hash function
// ipad = 0x36 byte repeated for key length
// opad = 0x5c byte repeated for key length
// hmac = H([key ^ opad] H([key ^ ipad] text))
 
type hmac struct {
size int
blocksize int
key, tmp []byte
outer, inner hash.Hash
}
 
func (h *hmac) tmpPad(xor byte) {
for i, k := range h.key {
h.tmp[i] = xor ^ k
}
for i := len(h.key); i < h.blocksize; i++ {
h.tmp[i] = xor
}
}
 
func (h *hmac) Sum(in []byte) []byte {
origLen := len(in)
in = h.inner.Sum(in)
h.tmpPad(0x5c)
copy(h.tmp[h.blocksize:], in[origLen:])
h.outer.Reset()
h.outer.Write(h.tmp)
return h.outer.Sum(in[:origLen])
}
 
func (h *hmac) Write(p []byte) (n int, err error) {
return h.inner.Write(p)
}
 
func (h *hmac) Size() int { return h.size }
 
func (h *hmac) BlockSize() int { return h.blocksize }
 
func (h *hmac) Reset() {
h.inner.Reset()
h.tmpPad(0x36)
h.inner.Write(h.tmp[0:h.blocksize])
}
 
// New returns a new HMAC hash using the given hash.Hash type and key.
func New(h func() hash.Hash, key []byte) hash.Hash {
hm := new(hmac)
hm.outer = h()
hm.inner = h()
hm.size = hm.inner.Size()
hm.blocksize = hm.inner.BlockSize()
hm.tmp = make([]byte, hm.blocksize+hm.size)
if len(key) > hm.blocksize {
// If key is too big, hash it.
hm.outer.Write(key)
key = hm.outer.Sum(nil)
}
hm.key = make([]byte, len(key))
copy(hm.key, key)
hm.Reset()
return hm
}
/sha256/sha256block.go
0,0 → 1,129
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// SHA256 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
 
package sha256
 
var _K = []uint32{
0x428a2f98,
0x71374491,
0xb5c0fbcf,
0xe9b5dba5,
0x3956c25b,
0x59f111f1,
0x923f82a4,
0xab1c5ed5,
0xd807aa98,
0x12835b01,
0x243185be,
0x550c7dc3,
0x72be5d74,
0x80deb1fe,
0x9bdc06a7,
0xc19bf174,
0xe49b69c1,
0xefbe4786,
0x0fc19dc6,
0x240ca1cc,
0x2de92c6f,
0x4a7484aa,
0x5cb0a9dc,
0x76f988da,
0x983e5152,
0xa831c66d,
0xb00327c8,
0xbf597fc7,
0xc6e00bf3,
0xd5a79147,
0x06ca6351,
0x14292967,
0x27b70a85,
0x2e1b2138,
0x4d2c6dfc,
0x53380d13,
0x650a7354,
0x766a0abb,
0x81c2c92e,
0x92722c85,
0xa2bfe8a1,
0xa81a664b,
0xc24b8b70,
0xc76c51a3,
0xd192e819,
0xd6990624,
0xf40e3585,
0x106aa070,
0x19a4c116,
0x1e376c08,
0x2748774c,
0x34b0bcb5,
0x391c0cb3,
0x4ed8aa4a,
0x5b9cca4f,
0x682e6ff3,
0x748f82ee,
0x78a5636f,
0x84c87814,
0x8cc70208,
0x90befffa,
0xa4506ceb,
0xbef9a3f7,
0xc67178f2,
}
 
func _Block(dig *digest, p []byte) int {
var w [64]uint32
n := 0
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= _Chunk {
// Can interlace the computation of w with the
// rounds below if needed for speed.
for i := 0; i < 16; i++ {
j := i * 4
w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
}
for i := 16; i < 64; i++ {
t1 := (w[i-2]>>17 | w[i-2]<<(32-17)) ^ (w[i-2]>>19 | w[i-2]<<(32-19)) ^ (w[i-2] >> 10)
 
t2 := (w[i-15]>>7 | w[i-15]<<(32-7)) ^ (w[i-15]>>18 | w[i-15]<<(32-18)) ^ (w[i-15] >> 3)
 
w[i] = t1 + w[i-7] + t2 + w[i-16]
}
 
a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
 
for i := 0; i < 64; i++ {
t1 := h + ((e>>6 | e<<(32-6)) ^ (e>>11 | e<<(32-11)) ^ (e>>25 | e<<(32-25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
 
t2 := ((a>>2 | a<<(32-2)) ^ (a>>13 | a<<(32-13)) ^ (a>>22 | a<<(32-22))) + ((a & b) ^ (a & c) ^ (b & c))
 
h = g
g = f
f = e
e = d + t1
d = c
c = b
b = a
a = t1 + t2
}
 
h0 += a
h1 += b
h2 += c
h3 += d
h4 += e
h5 += f
h6 += g
h7 += h
 
p = p[_Chunk:]
n += _Chunk
}
 
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
return n
}
/sha256/sha256_test.go
0,0 → 1,125
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// SHA256 hash algorithm. See FIPS 180-2.
 
package sha256
 
import (
"fmt"
"io"
"testing"
)
 
type sha256Test struct {
out string
in string
}
 
var golden = []sha256Test{
{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""},
{"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "a"},
{"fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603", "ab"},
{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc"},
{"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589", "abcd"},
{"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c", "abcde"},
{"bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721", "abcdef"},
{"7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a", "abcdefg"},
{"9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab", "abcdefgh"},
{"19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f", "abcdefghi"},
{"72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0", "abcdefghij"},
{"a144061c271f152da4d151034508fed1c138b8c976339de229c3bb6d4bbb4fce", "Discard medicine more than two years old."},
{"6dae5caa713a10ad04b46028bf6dad68837c581616a1589a265a11288d4bb5c4", "He who has a shady past knows that nice guys finish last."},
{"ae7a702a9509039ddbf29f0765e70d0001177914b86459284dab8b348c2dce3f", "I wouldn't marry him with a ten foot pole."},
{"6748450b01c568586715291dfa3ee018da07d36bb7ea6f180c1af6270215c64f", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
{"14b82014ad2b11f661b5ae6a99b75105c2ffac278cd071cd6c05832793635774", "The days of the digital watch are numbered. -Tom Stoppard"},
{"7102cfd76e2e324889eece5d6c41921b1e142a4ac5a2692be78803097f6a48d8", "Nepal premier won't resign."},
{"23b1018cd81db1d67983c5f7417c44da9deb582459e378d7a068552ea649dc9f", "For every action there is an equal and opposite government program."},
{"8001f190dfb527261c4cfcab70c98e8097a7a1922129bc4096950e57c7999a5a", "His money is twice tainted: 'taint yours and 'taint mine."},
{"8c87deb65505c3993eb24b7a150c4155e82eee6960cf0c3a8114ff736d69cad5", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
{"bfb0a67a19cdec3646498b2e0f751bddc41bba4b7f30081b0b932aad214d16d7", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
{"7f9a0b9bf56332e19f5a0ec1ad9c1425a153da1c624868fda44561d6b74daf36", "size: a.out: bad magic"},
{"b13f81b8aad9e3666879af19886140904f7f429ef083286195982a7588858cfc", "The major problem is with sendmail. -Mark Horton"},
{"b26c38d61519e894480c70c8374ea35aa0ad05b2ae3d6674eec5f52a69305ed4", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
{"049d5e26d4f10222cd841a119e38bd8d2e0d1129728688449575d4ff42b842c1", "If the enemy is within range, then so are you."},
{"0e116838e3cc1c1a14cd045397e29b4d087aa11b0853fc69ec82e90330d60949", "It's well we cannot hear the screams/That we create in others' dreams."},
{"4f7d8eb5bcf11de2a56b971021a444aa4eafd6ecd0f307b5109e4e776cd0fe46", "You remind me of a TV show, but that's all right: I watch it anyway."},
{"61c0cc4c4bd8406d5120b3fb4ebc31ce87667c162f29468b3c779675a85aebce", "C is as portable as Stonehedge!!"},
{"1fb2eb3688093c4a3f80cd87a5547e2ce940a4f923243a79a2a1e242220693ac", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
{"395585ce30617b62c80b93e8208ce866d4edc811a177fdb4b82d3911d8696423", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
{"4f9b189a13d030838269dce846b16a1ce9ce81fe63e65de2f636863336a98fe6", "How can you write a big system without C++? -Paul Glick"},
}
 
var golden224 = []sha256Test{
{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""},
{"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", "a"},
{"db3cda86d4429a1d39c148989566b38f7bda0156296bd364ba2f878b", "ab"},
{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc"},
{"a76654d8e3550e9a2d67a0eeb6c67b220e5885eddd3fde135806e601", "abcd"},
{"bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6", "abcde"},
{"7043631cb415556a275a4ebecb802c74ee9f6153908e1792a90b6a98", "abcdef"},
{"d1884e711701ad81abe0c77a3b0ea12e19ba9af64077286c72fc602d", "abcdefg"},
{"17eb7d40f0356f8598e89eafad5f6c759b1f822975d9c9b737c8a517", "abcdefgh"},
{"aeb35915346c584db820d2de7af3929ffafef9222a9bcb26516c7334", "abcdefghi"},
{"d35e1e5af29ddb0d7e154357df4ad9842afee527c689ee547f753188", "abcdefghij"},
{"19297f1cef7ddc8a7e947f5c5a341e10f7245045e425db67043988d7", "Discard medicine more than two years old."},
{"0f10c2eb436251f777fbbd125e260d36aecf180411726c7c885f599a", "He who has a shady past knows that nice guys finish last."},
{"4d1842104919f314cad8a3cd20b3cba7e8ed3e7abed62b57441358f6", "I wouldn't marry him with a ten foot pole."},
{"a8ba85c6fe0c48fbffc72bbb2f03fcdbc87ae2dc7a56804d1590fb3b", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
{"5543fbab26e67e8885b1a852d567d1cb8b9bfe42e0899584c50449a9", "The days of the digital watch are numbered. -Tom Stoppard"},
{"65ca107390f5da9efa05d28e57b221657edc7e43a9a18fb15b053ddb", "Nepal premier won't resign."},
{"84953962be366305a9cc9b5cd16ed019edc37ac96c0deb3e12cca116", "For every action there is an equal and opposite government program."},
{"35a189ce987151dfd00b3577583cc6a74b9869eecf894459cb52038d", "His money is twice tainted: 'taint yours and 'taint mine."},
{"2fc333713983edfd4ef2c0da6fb6d6415afb94987c91e4069eb063e6", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
{"cbe32d38d577a1b355960a4bc3c659c2dc4670859a19777a875842c4", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
{"a2dc118ce959e027576413a7b440c875cdc8d40df9141d6ef78a57e1", "size: a.out: bad magic"},
{"d10787e24052bcff26dc484787a54ed819e4e4511c54890ee977bf81", "The major problem is with sendmail. -Mark Horton"},
{"62efcf16ab8a893acdf2f348aaf06b63039ff1bf55508c830532c9fb", "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
{"3e9b7e4613c59f58665104c5fa86c272db5d3a2ff30df5bb194a5c99", "If the enemy is within range, then so are you."},
{"5999c208b8bdf6d471bb7c359ac5b829e73a8211dff686143a4e7f18", "It's well we cannot hear the screams/That we create in others' dreams."},
{"3b2d67ff54eabc4ef737b14edf87c64280ef582bcdf2a6d56908b405", "You remind me of a TV show, but that's all right: I watch it anyway."},
{"d0733595d20e4d3d6b5c565a445814d1bbb2fd08b9a3b8ffb97930c6", "C is as portable as Stonehedge!!"},
{"43fb8aeed8a833175c9295c1165415f98c866ef08a4922959d673507", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
{"ec18e66e93afc4fb1604bc2baedbfd20b44c43d76e65c0996d7851c6", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
{"86ed2eaa9c75ba98396e5c9fb2f679ecf0ea2ed1e0ee9ceecb4a9332", "How can you write a big system without C++? -Paul Glick"},
}
 
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("sha256[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
for i := 0; i < len(golden224); i++ {
g := golden224[i]
c := New224()
for j := 0; j < 3; j++ {
if j < 2 {
io.WriteString(c, g.in)
} else {
io.WriteString(c, g.in[0:len(g.in)/2])
c.Sum(nil)
io.WriteString(c, g.in[len(g.in)/2:])
}
s := fmt.Sprintf("%x", c.Sum(nil))
if s != g.out {
t.Fatalf("sha224[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
}
}
/sha256/sha256.go
0,0 → 1,172
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package sha256 implements the SHA224 and SHA256 hash algorithms as defined
// in FIPS 180-2.
package sha256
 
import (
"crypto"
"hash"
)
 
func init() {
crypto.RegisterHash(crypto.SHA224, New224)
crypto.RegisterHash(crypto.SHA256, New)
}
 
// The size of a SHA256 checksum in bytes.
const Size = 32
 
// The size of a SHA224 checksum in bytes.
const Size224 = 28
 
// The blocksize of SHA256 and SHA224 in bytes.
const BlockSize = 64
 
const (
_Chunk = 64
_Init0 = 0x6A09E667
_Init1 = 0xBB67AE85
_Init2 = 0x3C6EF372
_Init3 = 0xA54FF53A
_Init4 = 0x510E527F
_Init5 = 0x9B05688C
_Init6 = 0x1F83D9AB
_Init7 = 0x5BE0CD19
_Init0_224 = 0xC1059ED8
_Init1_224 = 0x367CD507
_Init2_224 = 0x3070DD17
_Init3_224 = 0xF70E5939
_Init4_224 = 0xFFC00B31
_Init5_224 = 0x68581511
_Init6_224 = 0x64F98FA7
_Init7_224 = 0xBEFA4FA4
)
 
// digest represents the partial evaluation of a checksum.
type digest struct {
h [8]uint32
x [_Chunk]byte
nx int
len uint64
is224 bool // mark if this digest is SHA-224
}
 
func (d *digest) Reset() {
if !d.is224 {
d.h[0] = _Init0
d.h[1] = _Init1
d.h[2] = _Init2
d.h[3] = _Init3
d.h[4] = _Init4
d.h[5] = _Init5
d.h[6] = _Init6
d.h[7] = _Init7
} else {
d.h[0] = _Init0_224
d.h[1] = _Init1_224
d.h[2] = _Init2_224
d.h[3] = _Init3_224
d.h[4] = _Init4_224
d.h[5] = _Init5_224
d.h[6] = _Init6_224
d.h[7] = _Init7_224
}
d.nx = 0
d.len = 0
}
 
// New returns a new hash.Hash computing the SHA256 checksum.
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
 
// New224 returns a new hash.Hash computing the SHA224 checksum.
func New224() hash.Hash {
d := new(digest)
d.is224 = true
d.Reset()
return d
}
 
func (d *digest) Size() int {
if !d.is224 {
return Size
}
return Size224
}
 
func (d *digest) BlockSize() int { return BlockSize }
 
func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)
d.len += uint64(nn)
if d.nx > 0 {
n := len(p)
if n > _Chunk-d.nx {
n = _Chunk - d.nx
}
for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i]
}
d.nx += n
if d.nx == _Chunk {
_Block(d, d.x[0:])
d.nx = 0
}
p = p[n:]
}
n := _Block(d, p)
p = p[n:]
if len(p) > 0 {
d.nx = copy(d.x[:], p)
}
return
}
 
func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing.
d := *d0
 
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
tmp[0] = 0x80
if len%64 < 56 {
d.Write(tmp[0 : 56-len%64])
} else {
d.Write(tmp[0 : 64+56-len%64])
}
 
// Length in bits.
len <<= 3
for i := uint(0); i < 8; i++ {
tmp[i] = byte(len >> (56 - 8*i))
}
d.Write(tmp[0:8])
 
if d.nx != 0 {
panic("d.nx != 0")
}
 
h := d.h[:]
size := Size
if d.is224 {
h = d.h[:7]
size = Size224
}
 
var digest [Size]byte
for i, s := range h {
digest[i*4] = byte(s >> 24)
digest[i*4+1] = byte(s >> 16)
digest[i*4+2] = byte(s >> 8)
digest[i*4+3] = byte(s)
}
 
return append(in, digest[:size]...)
}
/cipher/cbc_aes_test.go
0,0 → 1,89
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// CBC AES test vectors.
 
// See U.S. National Institute of Standards and Technology (NIST)
// Special Publication 800-38A, ``Recommendation for Block Cipher
// Modes of Operation,'' 2001 Edition, pp. 24-29.
 
package cipher
 
import (
"bytes"
"crypto/aes"
"testing"
)
 
var cbcAESTests = []struct {
name string
key []byte
iv []byte
in []byte
out []byte
}{
// NIST SP 800-38A pp 27-29
{
"CBC-AES128",
commonKey128,
commonIV,
commonInput,
[]byte{
0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
},
},
{
"CBC-AES192",
commonKey192,
commonIV,
commonInput,
[]byte{
0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a,
0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0,
0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd,
},
},
{
"CBC-AES256",
commonKey256,
commonIV,
commonInput,
[]byte{
0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
},
},
}
 
func TestCBC_AES(t *testing.T) {
for _, tt := range cbcAESTests {
test := tt.name
 
c, err := aes.NewCipher(tt.key)
if err != nil {
t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
continue
}
 
encrypter := NewCBCEncrypter(c, tt.iv)
d := make([]byte, len(tt.in))
encrypter.CryptBlocks(d, tt.in)
if !bytes.Equal(tt.out, d) {
t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test, d, tt.out)
}
 
decrypter := NewCBCDecrypter(c, tt.iv)
p := make([]byte, len(d))
decrypter.CryptBlocks(p, d)
if !bytes.Equal(tt.in, p) {
t.Errorf("%s: CBCDecrypter\nhave %x\nwant %x", test, d, tt.in)
}
}
}
/cipher/ctr_aes_test.go
0,0 → 1,101
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// CTR AES test vectors.
 
// See U.S. National Institute of Standards and Technology (NIST)
// Special Publication 800-38A, ``Recommendation for Block Cipher
// Modes of Operation,'' 2001 Edition, pp. 55-58.
 
package cipher
 
import (
"bytes"
"crypto/aes"
"testing"
)
 
var commonCounter = []byte{0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}
 
var ctrAESTests = []struct {
name string
key []byte
iv []byte
in []byte
out []byte
}{
// NIST SP 800-38A pp 55-58
{
"CTR-AES128",
commonKey128,
commonCounter,
commonInput,
[]byte{
0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee,
},
},
{
"CTR-AES192",
commonKey192,
commonCounter,
commonInput,
[]byte{
0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b,
0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef, 0xd5, 0xcc, 0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94,
0x1e, 0x36, 0xb2, 0x6b, 0xd1, 0xeb, 0xc6, 0x70, 0xd1, 0xbd, 0x1d, 0x66, 0x56, 0x20, 0xab, 0xf7,
0x4f, 0x78, 0xa7, 0xf6, 0xd2, 0x98, 0x09, 0x58, 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50,
},
},
{
"CTR-AES256",
commonKey256,
commonCounter,
commonInput,
[]byte{
0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6,
},
},
}
 
func TestCTR_AES(t *testing.T) {
for _, tt := range ctrAESTests {
test := tt.name
 
c, err := aes.NewCipher(tt.key)
if err != nil {
t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
continue
}
 
for j := 0; j <= 5; j += 5 {
in := tt.in[0 : len(tt.in)-j]
ctr := NewCTR(c, tt.iv)
encrypted := make([]byte, len(in))
ctr.XORKeyStream(encrypted, in)
if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) {
t.Errorf("%s/%d: CTR\ninpt %x\nhave %x\nwant %x", test, len(in), in, encrypted, out)
}
}
 
for j := 0; j <= 7; j += 7 {
in := tt.out[0 : len(tt.out)-j]
ctr := NewCTR(c, tt.iv)
plain := make([]byte, len(in))
ctr.XORKeyStream(plain, in)
if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) {
t.Errorf("%s/%d: CTRReader\nhave %x\nwant %x", test, len(out), plain, out)
}
}
 
if t.Failed() {
break
}
}
}
/cipher/ofb_test.go
0,0 → 1,101
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// OFB AES test vectors.
 
// See U.S. National Institute of Standards and Technology (NIST)
// Special Publication 800-38A, ``Recommendation for Block Cipher
// Modes of Operation,'' 2001 Edition, pp. 52-55.
 
package cipher
 
import (
"bytes"
"crypto/aes"
"testing"
)
 
type ofbTest struct {
name string
key []byte
iv []byte
in []byte
out []byte
}
 
var ofbTests = []ofbTest{
// NIST SP 800-38A pp 52-55
{
"OFB-AES128",
commonKey128,
commonIV,
commonInput,
[]byte{
0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e,
},
},
{
"OFB-AES192",
commonKey192,
commonIV,
commonInput,
[]byte{
0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a,
},
},
{
"OFB-AES256",
commonKey256,
commonIV,
commonInput,
[]byte{
0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84,
},
},
}
 
func TestOFB(t *testing.T) {
for _, tt := range ofbTests {
test := tt.name
 
c, err := aes.NewCipher(tt.key)
if err != nil {
t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
continue
}
 
for j := 0; j <= 5; j += 5 {
plaintext := tt.in[0 : len(tt.in)-j]
ofb := NewOFB(c, tt.iv)
ciphertext := make([]byte, len(plaintext))
ofb.XORKeyStream(ciphertext, plaintext)
if !bytes.Equal(ciphertext, tt.out[:len(plaintext)]) {
t.Errorf("%s/%d: encrypting\ninput % x\nhave % x\nwant % x", test, len(plaintext), plaintext, ciphertext, tt.out)
}
}
 
for j := 0; j <= 5; j += 5 {
ciphertext := tt.out[0 : len(tt.in)-j]
ofb := NewOFB(c, tt.iv)
plaintext := make([]byte, len(ciphertext))
ofb.XORKeyStream(plaintext, ciphertext)
if !bytes.Equal(plaintext, tt.in[:len(ciphertext)]) {
t.Errorf("%s/%d: decrypting\nhave % x\nwant % x", test, len(ciphertext), plaintext, tt.in)
}
}
 
if t.Failed() {
break
}
}
}
/cipher/ofb.go
0,0 → 1,44
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// OFB (Output Feedback) Mode.
 
package cipher
 
type ofb struct {
b Block
out []byte
outUsed int
}
 
// NewOFB returns a Stream that encrypts or decrypts using the block cipher b
// in output feedback mode. The initialization vector iv's length must be equal
// to b's block size.
func NewOFB(b Block, iv []byte) Stream {
blockSize := b.BlockSize()
if len(iv) != blockSize {
return nil
}
 
x := &ofb{
b: b,
out: make([]byte, blockSize),
outUsed: 0,
}
b.Encrypt(x.out, iv)
 
return x
}
 
func (x *ofb) XORKeyStream(dst, src []byte) {
for i, s := range src {
if x.outUsed == len(x.out) {
x.b.Encrypt(x.out, x.out)
x.outUsed = 0
}
 
dst[i] = s ^ x.out[x.outUsed]
x.outUsed++
}
}
/cipher/io.go
0,0 → 1,54
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package cipher
 
import "io"
 
// The Stream* objects are so simple that all their members are public. Users
// can create them themselves.
 
// StreamReader wraps a Stream into an io.Reader. It calls XORKeyStream
// to process each slice of data which passes through.
type StreamReader struct {
S Stream
R io.Reader
}
 
func (r StreamReader) Read(dst []byte) (n int, err error) {
n, err = r.R.Read(dst)
r.S.XORKeyStream(dst[:n], dst[:n])
return
}
 
// StreamWriter wraps a Stream into an io.Writer. It calls XORKeyStream
// to process each slice of data which passes through. If any Write call
// returns short then the StreamWriter is out of sync and must be discarded.
type StreamWriter struct {
S Stream
W io.Writer
Err error
}
 
func (w StreamWriter) Write(src []byte) (n int, err error) {
if w.Err != nil {
return 0, w.Err
}
c := make([]byte, len(src))
w.S.XORKeyStream(c, src)
n, err = w.W.Write(c)
if n != len(src) {
if err == nil { // should never happen
err = io.ErrShortWrite
}
w.Err = err
}
return
}
 
func (w StreamWriter) Close() error {
// This saves us from either requiring a WriteCloser or having a
// StreamWriterCloser.
return w.W.(io.Closer).Close()
}
/cipher/common_test.go
0,0 → 1,28
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package cipher
 
// Common values for tests.
 
var commonInput = []byte{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
}
 
var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
 
var commonKey192 = []byte{
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
}
 
var commonKey256 = []byte{
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
}
 
var commonIV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
/cipher/cbc.go
0,0 → 1,78
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Cipher block chaining (CBC) mode.
 
// CBC provides confidentiality by xoring (chaining) each plaintext block
// with the previous ciphertext block before applying the block cipher.
 
// See NIST SP 800-38A, pp 10-11
 
package cipher
 
type cbc struct {
b Block
blockSize int
iv []byte
tmp []byte
}
 
func newCBC(b Block, iv []byte) *cbc {
return &cbc{
b: b,
blockSize: b.BlockSize(),
iv: dup(iv),
tmp: make([]byte, b.BlockSize()),
}
}
 
type cbcEncrypter cbc
 
// NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining
// mode, using the given Block. The length of iv must be the same as the
// Block's block size.
func NewCBCEncrypter(b Block, iv []byte) BlockMode {
return (*cbcEncrypter)(newCBC(b, iv))
}
 
func (x *cbcEncrypter) BlockSize() int { return x.blockSize }
 
func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
for len(src) > 0 {
for i := 0; i < x.blockSize; i++ {
x.iv[i] ^= src[i]
}
x.b.Encrypt(x.iv, x.iv)
for i := 0; i < x.blockSize; i++ {
dst[i] = x.iv[i]
}
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
 
type cbcDecrypter cbc
 
// NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining
// mode, using the given Block. The length of iv must be the same as the
// Block's block size and must match the iv used to encrypt the data.
func NewCBCDecrypter(b Block, iv []byte) BlockMode {
return (*cbcDecrypter)(newCBC(b, iv))
}
 
func (x *cbcDecrypter) BlockSize() int { return x.blockSize }
 
func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
for len(src) > 0 {
x.b.Decrypt(x.tmp, src[:x.blockSize])
for i := 0; i < x.blockSize; i++ {
x.tmp[i] ^= x.iv[i]
x.iv[i] = src[i]
dst[i] = x.tmp[i]
}
 
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
/cipher/ctr.go
0,0 → 1,55
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Counter (CTR) mode.
 
// CTR converts a block cipher into a stream cipher by
// repeatedly encrypting an incrementing counter and
// xoring the resulting stream of data with the input.
 
// See NIST SP 800-38A, pp 13-15
 
package cipher
 
type ctr struct {
b Block
ctr []byte
out []byte
outUsed int
}
 
// NewCTR returns a Stream which encrypts/decrypts using the given Block in
// counter mode. The length of iv must be the same as the Block's block size.
func NewCTR(block Block, iv []byte) Stream {
if len(iv) != block.BlockSize() {
panic("cipher.NewCTR: iv length must equal block size")
}
 
return &ctr{
b: block,
ctr: dup(iv),
out: make([]byte, len(iv)),
outUsed: len(iv),
}
}
 
func (x *ctr) XORKeyStream(dst, src []byte) {
for i := 0; i < len(src); i++ {
if x.outUsed == len(x.ctr) {
x.b.Encrypt(x.out, x.ctr)
x.outUsed = 0
 
// Increment counter
for i := len(x.ctr) - 1; i >= 0; i-- {
x.ctr[i]++
if x.ctr[i] != 0 {
break
}
}
}
 
dst[i] = src[i] ^ x.out[x.outUsed]
x.outUsed++
}
}
/cipher/cfb_test.go
0,0 → 1,35
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package cipher
 
import (
"bytes"
"crypto/aes"
"crypto/rand"
"testing"
)
 
func TestCFB(t *testing.T) {
block, err := aes.NewCipher(commonKey128)
if err != nil {
t.Error(err)
return
}
 
plaintext := []byte("this is the plaintext")
iv := make([]byte, block.BlockSize())
rand.Reader.Read(iv)
cfb := NewCFBEncrypter(block, iv)
ciphertext := make([]byte, len(plaintext))
cfb.XORKeyStream(ciphertext, plaintext)
 
cfbdec := NewCFBDecrypter(block, iv)
plaintextCopy := make([]byte, len(plaintext))
cfbdec.XORKeyStream(plaintextCopy, ciphertext)
 
if !bytes.Equal(plaintextCopy, plaintext) {
t.Errorf("got: %x, want: %x", plaintextCopy, plaintext)
}
}
/cipher/cfb.go
0,0 → 1,64
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// CFB (Cipher Feedback) Mode.
 
package cipher
 
type cfb struct {
b Block
out []byte
outUsed int
decrypt bool
}
 
// NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode,
// using the given Block. The iv must be the same length as the Block's block
// size.
func NewCFBEncrypter(block Block, iv []byte) Stream {
return newCFB(block, iv, false)
}
 
// NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode,
// using the given Block. The iv must be the same length as the Block's block
// size.
func NewCFBDecrypter(block Block, iv []byte) Stream {
return newCFB(block, iv, true)
}
 
func newCFB(block Block, iv []byte, decrypt bool) Stream {
blockSize := block.BlockSize()
if len(iv) != blockSize {
return nil
}
 
x := &cfb{
b: block,
out: make([]byte, blockSize),
outUsed: 0,
decrypt: decrypt,
}
block.Encrypt(x.out, iv)
 
return x
}
 
func (x *cfb) XORKeyStream(dst, src []byte) {
for i := 0; i < len(src); i++ {
if x.outUsed == len(x.out) {
x.b.Encrypt(x.out, x.out)
x.outUsed = 0
}
 
if x.decrypt {
t := src[i]
dst[i] = src[i] ^ x.out[x.outUsed]
x.out[x.outUsed] = t
} else {
x.out[x.outUsed] ^= src[i]
dst[i] = x.out[x.outUsed]
}
x.outUsed++
}
}
/cipher/cipher.go
0,0 → 1,63
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package cipher implements standard block cipher modes that can be wrapped
// around low-level block cipher implementations.
// See http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html
// and NIST Special Publication 800-38A.
package cipher
 
// A Block represents an implementation of block cipher
// using a given key. It provides the capability to encrypt
// or decrypt individual blocks. The mode implementations
// extend that capability to streams of blocks.
type Block interface {
// BlockSize returns the cipher's block size.
BlockSize() int
 
// Encrypt encrypts the first block in src into dst.
// Dst and src may point at the same memory.
Encrypt(dst, src []byte)
 
// Decrypt decrypts the first block in src into dst.
// Dst and src may point at the same memory.
Decrypt(dst, src []byte)
}
 
// A Stream represents a stream cipher.
type Stream interface {
// XORKeyStream XORs each byte in the given slice with a byte from the
// cipher's key stream. Dst and src may point to the same memory.
XORKeyStream(dst, src []byte)
}
 
// A BlockMode represents a block cipher running in a block-based mode (CBC,
// ECB etc).
type BlockMode interface {
// BlockSize returns the mode's block size.
BlockSize() int
 
// CryptBlocks encrypts or decrypts a number of blocks. The length of
// src must be a multiple of the block size. Dst and src may point to
// the same memory.
CryptBlocks(dst, src []byte)
}
 
// Utility routines
 
func shift1(dst, src []byte) byte {
var b byte
for i := len(src) - 1; i >= 0; i-- {
bb := src[i] >> 7
dst[i] = src[i]<<1 | b
b = bb
}
return b
}
 
func dup(p []byte) []byte {
q := make([]byte, len(p))
copy(q, p)
return q
}
/des/const.go
0,0 → 1,139
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// Package des implements the Data Encryption Standard (DES) and the
// Triple Data Encryption Algorithm (TDEA) as defined
// in U.S. Federal Information Processing Standards Publication 46-3.
package des
 
// Used to perform an initial permutation of a 64-bit input block.
var initialPermutation = [64]byte{
6, 14, 22, 30, 38, 46, 54, 62,
4, 12, 20, 28, 36, 44, 52, 60,
2, 10, 18, 26, 34, 42, 50, 58,
0, 8, 16, 24, 32, 40, 48, 56,
7, 15, 23, 31, 39, 47, 55, 63,
5, 13, 21, 29, 37, 45, 53, 61,
3, 11, 19, 27, 35, 43, 51, 59,
1, 9, 17, 25, 33, 41, 49, 57,
}
 
// Used to perform a final permutation of a 4-bit preoutput block. This is the
// inverse of initialPermutation
var finalPermutation = [64]byte{
24, 56, 16, 48, 8, 40, 0, 32,
25, 57, 17, 49, 9, 41, 1, 33,
26, 58, 18, 50, 10, 42, 2, 34,
27, 59, 19, 51, 11, 43, 3, 35,
28, 60, 20, 52, 12, 44, 4, 36,
29, 61, 21, 53, 13, 45, 5, 37,
30, 62, 22, 54, 14, 46, 6, 38,
31, 63, 23, 55, 15, 47, 7, 39,
}
 
// Used to expand an input block of 32 bits, producing an output block of 48
// bits.
var expansionFunction = [48]byte{
0, 31, 30, 29, 28, 27, 28, 27,
26, 25, 24, 23, 24, 23, 22, 21,
20, 19, 20, 19, 18, 17, 16, 15,
16, 15, 14, 13, 12, 11, 12, 11,
10, 9, 8, 7, 8, 7, 6, 5,
4, 3, 4, 3, 2, 1, 0, 31,
}
 
// Yields a 32-bit output from a 32-bit input
var permutationFunction = [32]byte{
16, 25, 12, 11, 3, 20, 4, 15,
31, 17, 9, 6, 27, 14, 1, 22,
30, 24, 8, 18, 0, 5, 29, 23,
13, 19, 2, 26, 10, 21, 28, 7,
}
 
// Used in the key schedule to select 56 bits
// from a 64-bit input.
var permutedChoice1 = [56]byte{
7, 15, 23, 31, 39, 47, 55, 63,
6, 14, 22, 30, 38, 46, 54, 62,
5, 13, 21, 29, 37, 45, 53, 61,
4, 12, 20, 28, 1, 9, 17, 25,
33, 41, 49, 57, 2, 10, 18, 26,
34, 42, 50, 58, 3, 11, 19, 27,
35, 43, 51, 59, 36, 44, 52, 60,
}
 
// Used in the key schedule to produce each subkey by selecting 48 bits from
// the 56-bit input
var permutedChoice2 = [48]byte{
42, 39, 45, 32, 55, 51, 53, 28,
41, 50, 35, 46, 33, 37, 44, 52,
30, 48, 40, 49, 29, 36, 43, 54,
15, 4, 25, 19, 9, 1, 26, 16,
5, 11, 23, 8, 12, 7, 17, 0,
22, 3, 10, 14, 6, 20, 27, 24,
}
 
// 8 S-boxes composed of 4 rows and 16 columns
// Used in the DES cipher function
var sBoxes = [8][4][16]uint8{
// S-box 1
{
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
},
// S-box 2
{
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
},
// S-box 3
{
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
},
// S-box 4
{
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
},
// S-box 5
{
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
},
// S-box 6
{
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
},
// S-box 7
{
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
},
// S-box 8
{
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
},
}
 
// Size of left rotation per round in each half of the key schedule
var ksRotations = [16]uint8{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}
/des/des_test.go
0,0 → 1,1497
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package des
 
import (
"bytes"
"testing"
)
 
type CryptTest struct {
key []byte
in []byte
out []byte
}
 
// some custom tests for DES
var encryptDESTests = []CryptTest{
{
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x8c, 0xa6, 0x4d, 0xe9, 0xc1, 0xb1, 0x23, 0xa7}},
{
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x35, 0x55, 0x50, 0xb2, 0x15, 0x0e, 0x24, 0x51}},
{
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x61, 0x7b, 0x3a, 0x0c, 0xe8, 0xf0, 0x71, 0x00}},
{
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0x92, 0x31, 0xf2, 0x36, 0xff, 0x9a, 0xa9, 0x5c}},
{
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xca, 0xaa, 0xaf, 0x4d, 0xea, 0xf1, 0xdb, 0xae}},
{
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x73, 0x59, 0xb2, 0x16, 0x3e, 0x4e, 0xdc, 0x58}},
{
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x6d, 0xce, 0x0d, 0xc9, 0x00, 0x65, 0x56, 0xa3}},
{
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0x9e, 0x84, 0xc5, 0xf3, 0x17, 0x0f, 0x8e, 0xff}},
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xd5, 0xd4, 0x4f, 0xf7, 0x20, 0x68, 0x3d, 0x0d}},
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x59, 0x73, 0x23, 0x56, 0xf3, 0x6f, 0xde, 0x06}},
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x56, 0xcc, 0x09, 0xe7, 0xcf, 0xdc, 0x4c, 0xef}},
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0x12, 0xc6, 0x26, 0xaf, 0x05, 0x8b, 0x43, 0x3b}},
{
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xa6, 0x8c, 0xdc, 0xa9, 0x0c, 0x90, 0x21, 0xf9}},
{
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x2a, 0x2b, 0xb0, 0x08, 0xdf, 0x97, 0xc2, 0xf2}},
{
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0xed, 0x39, 0xd9, 0x50, 0xfa, 0x74, 0xbc, 0xc4}},
{
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
[]byte{0xa9, 0x33, 0xf6, 0x18, 0x30, 0x23, 0xb3, 0x10}},
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
[]byte{0x17, 0x66, 0x8d, 0xfc, 0x72, 0x92, 0x53, 0x2d}},
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
[]byte{0xb4, 0xfd, 0x23, 0x16, 0x47, 0xa5, 0xbe, 0xc0}},
{
[]byte{0x0e, 0x32, 0x92, 0x32, 0xea, 0x6d, 0x0d, 0x73},
[]byte{0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{
[]byte{0x73, 0x65, 0x63, 0x52, 0x33, 0x74, 0x24, 0x3b}, // "secR3t$;"
[]byte{0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32}, // "a test12"
[]byte{0x37, 0x0d, 0xee, 0x2c, 0x1f, 0xb4, 0xf7, 0xa5}},
{
[]byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
[]byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
[]byte{0x2a, 0x8d, 0x69, 0xde, 0x9d, 0x5f, 0xdf, 0xf9}},
{
[]byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
[]byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678"
[]byte{0x21, 0xc6, 0x0d, 0xa5, 0x34, 0x24, 0x8b, 0xce}},
{
[]byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678"
[]byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
[]byte{0x94, 0xd4, 0x43, 0x6b, 0xc3, 0xb5, 0xb6, 0x93}},
{
[]byte{0x1f, 0x79, 0x90, 0x5f, 0x88, 0x01, 0xc8, 0x88}, // random
[]byte{0xc7, 0x46, 0x18, 0x73, 0xaf, 0x48, 0x5f, 0xb3}, // random
[]byte{0xb0, 0x93, 0x50, 0x88, 0xf9, 0x92, 0x44, 0x6a}},
{
[]byte{0xe6, 0xf4, 0xf2, 0xdb, 0x31, 0x42, 0x53, 0x01}, // random
[]byte{0xff, 0x3d, 0x25, 0x50, 0x12, 0xe3, 0x4a, 0xc5}, // random
[]byte{0x86, 0x08, 0xd3, 0xd1, 0x6c, 0x2f, 0xd2, 0x55}},
{
[]byte{0x69, 0xc1, 0x9d, 0xc1, 0x15, 0xc5, 0xfb, 0x2b}, // random
[]byte{0x1a, 0x22, 0x5c, 0xaf, 0x1f, 0x1d, 0xa3, 0xf9}, // random
[]byte{0x64, 0xba, 0x31, 0x67, 0x56, 0x91, 0x1e, 0xa7}},
{
[]byte{0x6e, 0x5e, 0xe2, 0x47, 0xc4, 0xbf, 0xf6, 0x51}, // random
[]byte{0x11, 0xc9, 0x57, 0xff, 0x66, 0x89, 0x0e, 0xf0}, // random
[]byte{0x94, 0xc5, 0x35, 0xb2, 0xc5, 0x8b, 0x39, 0x72}},
}
 
var weakKeyTests = []CryptTest{
{
[]byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
[]byte{0x55, 0x74, 0xc0, 0xbd, 0x7c, 0xdf, 0xf7, 0x39}, // random
nil},
{
[]byte{0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
[]byte{0xe8, 0xe1, 0xa7, 0xc1, 0xde, 0x11, 0x89, 0xaa}, // random
nil},
{
[]byte{0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1},
[]byte{0x50, 0x6a, 0x4b, 0x94, 0x3b, 0xed, 0x7d, 0xdc}, // random
nil},
{
[]byte{0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e},
[]byte{0x88, 0x81, 0x56, 0x38, 0xec, 0x3b, 0x1c, 0x97}, // random
nil},
{
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x17, 0xa0, 0x83, 0x62, 0x32, 0xfe, 0x9a, 0x0b}, // random
nil},
{
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0xca, 0x8f, 0xca, 0x1f, 0x50, 0xc5, 0x7b, 0x49}, // random
nil},
{
[]byte{0xe1, 0xe1, 0xe1, 0xe1, 0xf0, 0xf0, 0xf0, 0xf0},
[]byte{0xb1, 0xea, 0xad, 0x7d, 0xe7, 0xc3, 0x7a, 0x43}, // random
nil},
{
[]byte{0x1e, 0x1e, 0x1e, 0x1e, 0x0f, 0x0f, 0x0f, 0x0f},
[]byte{0xae, 0x74, 0x7d, 0x6f, 0xef, 0x16, 0xbb, 0x81}, // random
nil},
}
 
var semiWeakKeyTests = []CryptTest{
// key and out contain the semi-weak key pair
{
[]byte{0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e},
[]byte{0x12, 0xfa, 0x31, 0x16, 0xf9, 0xc5, 0x0a, 0xe4}, // random
[]byte{0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01}},
{
[]byte{0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1},
[]byte{0xb0, 0x4c, 0x7a, 0xee, 0xd2, 0xe5, 0x4d, 0xb7}, // random
[]byte{0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01}},
{
[]byte{0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe},
[]byte{0xa4, 0x81, 0xcd, 0xb1, 0x64, 0x6f, 0xd3, 0xbc}, // random
[]byte{0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01}},
{
[]byte{0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1},
[]byte{0xee, 0x27, 0xdd, 0x88, 0x4c, 0x22, 0xcd, 0xce}, // random
[]byte{0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e}},
{
[]byte{0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe},
[]byte{0x19, 0x3d, 0xcf, 0x97, 0x70, 0xfb, 0xab, 0xe1}, // random
[]byte{0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e}},
{
[]byte{0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe},
[]byte{0x7c, 0x82, 0x69, 0xe4, 0x1e, 0x86, 0x99, 0xd7}, // random
[]byte{0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1}},
}
 
// some custom tests for TripleDES
var encryptTripleDESTests = []CryptTest{
{
[]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x92, 0x95, 0xb5, 0x9b, 0xb3, 0x84, 0x73, 0x6e}},
{
[]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0xc1, 0x97, 0xf5, 0x58, 0x74, 0x8a, 0x20, 0xe7}},
{
[]byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x3e, 0x68, 0x0a, 0xa7, 0x8b, 0x75, 0xdf, 0x18}},
{
[]byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
[]byte{0x6d, 0x6a, 0x4a, 0x64, 0x4c, 0x7b, 0x8c, 0x91}},
{
[]byte{ // "abcdefgh12345678ABCDEFGH"
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
[]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}, // "00000000"
[]byte{0xe4, 0x61, 0xb7, 0x59, 0x68, 0x8b, 0xff, 0x66}},
{
[]byte{ // "abcdefgh12345678ABCDEFGH"
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
[]byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678"
[]byte{0xdb, 0xd0, 0x92, 0xde, 0xf8, 0x34, 0xff, 0x58}},
{
[]byte{ // "abcdefgh12345678ABCDEFGH"
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
[]byte{0xf0, 0xc5, 0x82, 0x22, 0xd3, 0xe6, 0x12, 0xd2}, // random
[]byte{0xba, 0xe4, 0x41, 0xb1, 0x3c, 0x37, 0x4d, 0xf4}},
{
[]byte{ // random
0xd3, 0x7d, 0x45, 0xee, 0x22, 0xe9, 0xcf, 0x52,
0xf4, 0x65, 0xa2, 0x4f, 0x70, 0xd1, 0x81, 0x8a,
0x3d, 0xbe, 0x2f, 0x39, 0xc7, 0x71, 0xd2, 0xe9},
[]byte{0x49, 0x53, 0xc3, 0xe9, 0x78, 0xdf, 0x9f, 0xaf}, // random
[]byte{0x53, 0x40, 0x51, 0x24, 0xd8, 0x3c, 0xf9, 0x88}},
{
[]byte{ // random
0xcb, 0x10, 0x7d, 0xda, 0x7e, 0x96, 0x57, 0x0a,
0xe8, 0xeb, 0xe8, 0x07, 0x8e, 0x87, 0xd3, 0x57,
0xb2, 0x61, 0x12, 0xb8, 0x2a, 0x90, 0xb7, 0x2f},
[]byte{0xa3, 0xc2, 0x60, 0xb1, 0x0b, 0xb7, 0x28, 0x6e}, // random
[]byte{0x56, 0x73, 0x7d, 0xfb, 0xb5, 0xa1, 0xc3, 0xde}},
}
 
// NIST Special Publication 800-20, Appendix A
// Key for use with Table A.1 tests
var tableA1Key = []byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
}
 
// Table A.1 Resulting Ciphertext from the Variable Plaintext Known Answer Test
var tableA1Tests = []CryptTest{
{nil, // 0
[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00}},
{nil, // 1
[]byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xdd, 0x7f, 0x12, 0x1c, 0xa5, 0x01, 0x56, 0x19}},
{nil, // 2
[]byte{0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x2e, 0x86, 0x53, 0x10, 0x4f, 0x38, 0x34, 0xea}},
{nil, // 3
[]byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x4b, 0xd3, 0x88, 0xff, 0x6c, 0xd8, 0x1d, 0x4f}},
{nil, // 4
[]byte{0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x20, 0xb9, 0xe7, 0x67, 0xb2, 0xfb, 0x14, 0x56}},
{nil, // 5
[]byte{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x55, 0x57, 0x93, 0x80, 0xd7, 0x71, 0x38, 0xef}},
{nil, // 6
[]byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x6c, 0xc5, 0xde, 0xfa, 0xaf, 0x04, 0x51, 0x2f}},
{nil, // 7
[]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x0d, 0x9f, 0x27, 0x9b, 0xa5, 0xd8, 0x72, 0x60}},
{nil, // 8
[]byte{0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xd9, 0x03, 0x1b, 0x02, 0x71, 0xbd, 0x5a, 0x0a}},
{nil, // 9
[]byte{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x42, 0x42, 0x50, 0xb3, 0x7c, 0x3d, 0xd9, 0x51}},
{nil, // 10
[]byte{0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xb8, 0x06, 0x1b, 0x7e, 0xcd, 0x9a, 0x21, 0xe5}},
{nil, // 11
[]byte{0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xf1, 0x5d, 0x0f, 0x28, 0x6b, 0x65, 0xbd, 0x28}},
{nil, // 12
[]byte{0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xad, 0xd0, 0xcc, 0x8d, 0x6e, 0x5d, 0xeb, 0xa1}},
{nil, // 13
[]byte{0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xe6, 0xd5, 0xf8, 0x27, 0x52, 0xad, 0x63, 0xd1}},
{nil, // 14
[]byte{0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xec, 0xbf, 0xe3, 0xbd, 0x3f, 0x59, 0x1a, 0x5e}},
{nil, // 15
[]byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xf3, 0x56, 0x83, 0x43, 0x79, 0xd1, 0x65, 0xcd}},
{nil, // 16
[]byte{0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x2b, 0x9f, 0x98, 0x2f, 0x20, 0x03, 0x7f, 0xa9}},
{nil, // 17
[]byte{0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x88, 0x9d, 0xe0, 0x68, 0xa1, 0x6f, 0x0b, 0xe6}},
{nil, // 18
[]byte{0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xe1, 0x9e, 0x27, 0x5d, 0x84, 0x6a, 0x12, 0x98}},
{nil, // 19
[]byte{0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x32, 0x9a, 0x8e, 0xd5, 0x23, 0xd7, 0x1a, 0xec}},
{nil, // 20
[]byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xe7, 0xfc, 0xe2, 0x25, 0x57, 0xd2, 0x3c, 0x97}},
{nil, // 21
[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0x12, 0xa9, 0xf5, 0x81, 0x7f, 0xf2, 0xd6, 0x5d}},
{nil, // 22
[]byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xa4, 0x84, 0xc3, 0xad, 0x38, 0xdc, 0x9c, 0x19}},
{nil, // 23
[]byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
[]byte{0xfb, 0xe0, 0x0a, 0x8a, 0x1e, 0xf8, 0xad, 0x72}},
{nil, // 24
[]byte{0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00},
[]byte{0x75, 0x0d, 0x07, 0x94, 0x07, 0x52, 0x13, 0x63}},
{nil, // 25
[]byte{0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00},
[]byte{0x64, 0xfe, 0xed, 0x9c, 0x72, 0x4c, 0x2f, 0xaf}},
{nil, // 26
[]byte{0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00},
[]byte{0xf0, 0x2b, 0x26, 0x3b, 0x32, 0x8e, 0x2b, 0x60}},
{nil, // 27
[]byte{0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
[]byte{0x9d, 0x64, 0x55, 0x5a, 0x9a, 0x10, 0xb8, 0x52}},
{nil, // 28
[]byte{0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
[]byte{0xd1, 0x06, 0xff, 0x0b, 0xed, 0x52, 0x55, 0xd7}},
{nil, // 29
[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00},
[]byte{0xe1, 0x65, 0x2c, 0x6b, 0x13, 0x8c, 0x64, 0xa5}},
{nil, // 30
[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00},
[]byte{0xe4, 0x28, 0x58, 0x11, 0x86, 0xec, 0x8f, 0x46}},
{nil, // 31
[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00},
[]byte{0xae, 0xb5, 0xf5, 0xed, 0xe2, 0x2d, 0x1a, 0x36}},
{nil, // 32
[]byte{0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00},
[]byte{0xe9, 0x43, 0xd7, 0x56, 0x8a, 0xec, 0x0c, 0x5c}},
{nil, // 33
[]byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00},
[]byte{0xdf, 0x98, 0xc8, 0x27, 0x6f, 0x54, 0xb0, 0x4b}},
{nil, // 34
[]byte{0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00},
[]byte{0xb1, 0x60, 0xe4, 0x68, 0x0f, 0x6c, 0x69, 0x6f}},
{nil, // 35
[]byte{0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00},
[]byte{0xfa, 0x07, 0x52, 0xb0, 0x7d, 0x9c, 0x4a, 0xb8}},
{nil, // 36
[]byte{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00},
[]byte{0xca, 0x3a, 0x2b, 0x03, 0x6d, 0xbc, 0x85, 0x02}},
{nil, // 37
[]byte{0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00},
[]byte{0x5e, 0x09, 0x05, 0x51, 0x7b, 0xb5, 0x9b, 0xcf}},
{nil, // 38
[]byte{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00},
[]byte{0x81, 0x4e, 0xeb, 0x3b, 0x91, 0xd9, 0x07, 0x26}},
{nil, // 39
[]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
[]byte{0x4d, 0x49, 0xdb, 0x15, 0x32, 0x91, 0x9c, 0x9f}},
{nil, // 40
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00},
[]byte{0x25, 0xeb, 0x5f, 0xc3, 0xf8, 0xcf, 0x06, 0x21}},
{nil, // 41
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00},
[]byte{0xab, 0x6a, 0x20, 0xc0, 0x62, 0x0d, 0x1c, 0x6f}},
{nil, // 42
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00},
[]byte{0x79, 0xe9, 0x0d, 0xbc, 0x98, 0xf9, 0x2c, 0xca}},
{nil, // 43
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
[]byte{0x86, 0x6e, 0xce, 0xdd, 0x80, 0x72, 0xbb, 0x0e}},
{nil, // 44
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00},
[]byte{0x8b, 0x54, 0x53, 0x6f, 0x2f, 0x3e, 0x64, 0xa8}},
{nil, // 45
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00},
[]byte{0xea, 0x51, 0xd3, 0x97, 0x55, 0x95, 0xb8, 0x6b}},
{nil, // 46
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00},
[]byte{0xca, 0xff, 0xc6, 0xac, 0x45, 0x42, 0xde, 0x31}},
{nil, // 47
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00},
[]byte{0x8d, 0xd4, 0x5a, 0x2d, 0xdf, 0x90, 0x79, 0x6c}},
{nil, // 48
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00},
[]byte{0x10, 0x29, 0xd5, 0x5e, 0x88, 0x0e, 0xc2, 0xd0}},
{nil, // 49
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00},
[]byte{0x5d, 0x86, 0xcb, 0x23, 0x63, 0x9d, 0xbe, 0xa9}},
{nil, // 50
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00},
[]byte{0x1d, 0x1c, 0xa8, 0x53, 0xae, 0x7c, 0x0c, 0x5f}},
{nil, // 51
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00},
[]byte{0xce, 0x33, 0x23, 0x29, 0x24, 0x8f, 0x32, 0x28}},
{nil, // 52
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00},
[]byte{0x84, 0x05, 0xd1, 0xab, 0xe2, 0x4f, 0xb9, 0x42}},
{nil, // 53
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00},
[]byte{0xe6, 0x43, 0xd7, 0x80, 0x90, 0xca, 0x42, 0x07}},
{nil, // 54
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
[]byte{0x48, 0x22, 0x1b, 0x99, 0x37, 0x74, 0x8a, 0x23}},
{nil, // 55
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
[]byte{0xdd, 0x7c, 0x0b, 0xbd, 0x61, 0xfa, 0xfd, 0x54}},
{nil, // 56
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80},
[]byte{0x2f, 0xbc, 0x29, 0x1a, 0x57, 0x0d, 0xb5, 0xc4}},
{nil, // 57
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40},
[]byte{0xe0, 0x7c, 0x30, 0xd7, 0xe4, 0xe2, 0x6e, 0x12}},
{nil, // 58
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
[]byte{0x09, 0x53, 0xe2, 0x25, 0x8e, 0x8e, 0x90, 0xa1}},
{nil, // 59
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
[]byte{0x5b, 0x71, 0x1b, 0xc4, 0xce, 0xeb, 0xf2, 0xee}},
{nil, // 60
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
[]byte{0xcc, 0x08, 0x3f, 0x1e, 0x6d, 0x9e, 0x85, 0xf6}},
{nil, // 61
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
[]byte{0xd2, 0xfd, 0x88, 0x67, 0xd5, 0x0d, 0x2d, 0xfe}},
{nil, // 62
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
[]byte{0x06, 0xe7, 0xea, 0x22, 0xce, 0x92, 0x70, 0x8f}},
{nil, // 63
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
[]byte{0x16, 0x6b, 0x40, 0xb4, 0x4a, 0xba, 0x4b, 0xd6}},
}
 
// Plaintext for use with Table A.2 tests
var tableA2Plaintext = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
// Table A.2 Resulting Ciphertext from the Variable Key Known Answer Test
var tableA2Tests = []CryptTest{
{ // 0
[]byte{
0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x95, 0xa8, 0xd7, 0x28, 0x13, 0xda, 0xa9, 0x4d}},
{ // 1
[]byte{
0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x0e, 0xec, 0x14, 0x87, 0xdd, 0x8c, 0x26, 0xd5}},
{ // 2
[]byte{
0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x7a, 0xd1, 0x6f, 0xfb, 0x79, 0xc4, 0x59, 0x26}},
{ // 3
[]byte{
0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xd3, 0x74, 0x62, 0x94, 0xca, 0x6a, 0x6c, 0xf3}},
{ // 4
[]byte{
0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x80, 0x9f, 0x5f, 0x87, 0x3c, 0x1f, 0xd7, 0x61}},
{ // 5
[]byte{
0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xc0, 0x2f, 0xaf, 0xfe, 0xc9, 0x89, 0xd1, 0xfc}},
{ // 6
[]byte{
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x46, 0x15, 0xaa, 0x1d, 0x33, 0xe7, 0x2f, 0x10}},
{ // 7
[]byte{
0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x20, 0x55, 0x12, 0x33, 0x50, 0xc0, 0x08, 0x58}},
{ // 8
[]byte{
0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xdf, 0x3b, 0x99, 0xd6, 0x57, 0x73, 0x97, 0xc8}},
{ // 9
[]byte{
0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x31, 0xfe, 0x17, 0x36, 0x9b, 0x52, 0x88, 0xc9}},
{ // 10
[]byte{
0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xdf, 0xdd, 0x3c, 0xc6, 0x4d, 0xae, 0x16, 0x42}},
{ // 11
[]byte{
0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x17, 0x8c, 0x83, 0xce, 0x2b, 0x39, 0x9d, 0x94}},
{ // 12
[]byte{
0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x50, 0xf6, 0x36, 0x32, 0x4a, 0x9b, 0x7f, 0x80}},
{ // 13
[]byte{
0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xa8, 0x46, 0x8e, 0xe3, 0xbc, 0x18, 0xf0, 0x6d}},
{ // 14
[]byte{
0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xa2, 0xdc, 0x9e, 0x92, 0xfd, 0x3c, 0xde, 0x92}},
{ // 15
[]byte{
0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xca, 0xc0, 0x9f, 0x79, 0x7d, 0x03, 0x12, 0x87}},
{ // 16
[]byte{
0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x90, 0xba, 0x68, 0x0b, 0x22, 0xae, 0xb5, 0x25}},
{ // 17
[]byte{
0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xce, 0x7a, 0x24, 0xf3, 0x50, 0xe2, 0x80, 0xb6}},
{ // 18
[]byte{
0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x88, 0x2b, 0xff, 0x0a, 0xa0, 0x1a, 0x0b, 0x87}},
{ // 19
[]byte{
0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x25, 0x61, 0x02, 0x88, 0x92, 0x45, 0x11, 0xc2}},
{ // 20
[]byte{
0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xc7, 0x15, 0x16, 0xc2, 0x9c, 0x75, 0xd1, 0x70}},
{ // 21
[]byte{
0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x51, 0x99, 0xc2, 0x9a, 0x52, 0xc9, 0xf0, 0x59}},
{ // 22
[]byte{
0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xc2, 0x2f, 0x0a, 0x29, 0x4a, 0x71, 0xf2, 0x9f}},
{ // 23
[]byte{
0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xee, 0x37, 0x14, 0x83, 0x71, 0x4c, 0x02, 0xea}},
{ // 24
[]byte{
0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xa8, 0x1f, 0xbd, 0x44, 0x8f, 0x9e, 0x52, 0x2f}},
{ // 25
[]byte{
0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x4f, 0x64, 0x4c, 0x92, 0xe1, 0x92, 0xdf, 0xed}},
{ // 26
[]byte{
0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0x1a, 0xfa, 0x9a, 0x66, 0xa6, 0xdf, 0x92, 0xae}},
{ // 27
[]byte{
0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01},
nil,
[]byte{0xb3, 0xc1, 0xcc, 0x71, 0x5c, 0xb8, 0x79, 0xd8}},
{ // 28
[]byte{
0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01},
nil,
[]byte{0x19, 0xd0, 0x32, 0xe6, 0x4a, 0xb0, 0xbd, 0x8b}},
{ // 29
[]byte{
0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01},
nil,
[]byte{0x3c, 0xfa, 0xa7, 0xa7, 0xdc, 0x87, 0x20, 0xdc}},
{ // 30
[]byte{
0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01},
nil,
[]byte{0xb7, 0x26, 0x5f, 0x7f, 0x44, 0x7a, 0xc6, 0xf3}},
{ // 31
[]byte{
0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01},
nil,
[]byte{0x9d, 0xb7, 0x3b, 0x3c, 0x0d, 0x16, 0x3f, 0x54}},
{ // 32
[]byte{
0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01},
nil,
[]byte{0x81, 0x81, 0xb6, 0x5b, 0xab, 0xf4, 0xa9, 0x75}},
{ // 33
[]byte{
0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01},
nil,
[]byte{0x93, 0xc9, 0xb6, 0x40, 0x42, 0xea, 0xa2, 0x40}},
{ // 34
[]byte{
0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01},
nil,
[]byte{0x55, 0x70, 0x53, 0x08, 0x29, 0x70, 0x55, 0x92}},
{ // 35
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01},
nil,
[]byte{0x86, 0x38, 0x80, 0x9e, 0x87, 0x87, 0x87, 0xa0}},
{ // 36
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01},
nil,
[]byte{0x41, 0xb9, 0xa7, 0x9a, 0xf7, 0x9a, 0xc2, 0x08}},
{ // 37
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01},
nil,
[]byte{0x7a, 0x9b, 0xe4, 0x2f, 0x20, 0x09, 0xa8, 0x92}},
{ // 38
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01},
nil,
[]byte{0x29, 0x03, 0x8d, 0x56, 0xba, 0x6d, 0x27, 0x45}},
{ // 39
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01},
nil,
[]byte{0x54, 0x95, 0xc6, 0xab, 0xf1, 0xe5, 0xdf, 0x51}},
{ // 40
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01},
nil,
[]byte{0xae, 0x13, 0xdb, 0xd5, 0x61, 0x48, 0x89, 0x33}},
{ // 41
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01},
nil,
[]byte{0x02, 0x4d, 0x1f, 0xfa, 0x89, 0x04, 0xe3, 0x89}},
{ // 42
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01},
nil,
[]byte{0xd1, 0x39, 0x97, 0x12, 0xf9, 0x9b, 0xf0, 0x2e}},
{ // 43
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01},
nil,
[]byte{0x14, 0xc1, 0xd7, 0xc1, 0xcf, 0xfe, 0xc7, 0x9e}},
{ // 44
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01},
nil,
[]byte{0x1d, 0xe5, 0x27, 0x9d, 0xae, 0x3b, 0xed, 0x6f}},
{ // 45
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01},
nil,
[]byte{0xe9, 0x41, 0xa3, 0x3f, 0x85, 0x50, 0x13, 0x03}},
{ // 46
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01},
nil,
[]byte{0xda, 0x99, 0xdb, 0xbc, 0x9a, 0x03, 0xf3, 0x79}},
{ // 47
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01},
nil,
[]byte{0xb7, 0xfc, 0x92, 0xf9, 0x1d, 0x8e, 0x92, 0xe9}},
{ // 48
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01},
nil,
[]byte{0xae, 0x8e, 0x5c, 0xaa, 0x3c, 0xa0, 0x4e, 0x85}},
{ // 49
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80},
nil,
[]byte{0x9c, 0xc6, 0x2d, 0xf4, 0x3b, 0x6e, 0xed, 0x74}},
{ // 50
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40},
nil,
[]byte{0xd8, 0x63, 0xdb, 0xb5, 0xc5, 0x9a, 0x91, 0xa0}},
{ // 50
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20},
nil,
[]byte{0xa1, 0xab, 0x21, 0x90, 0x54, 0x5b, 0x91, 0xd7}},
{ // 52
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10},
nil,
[]byte{0x08, 0x75, 0x04, 0x1e, 0x64, 0xc5, 0x70, 0xf7}},
{ // 53
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08},
nil,
[]byte{0x5a, 0x59, 0x45, 0x28, 0xbe, 0xbe, 0xf1, 0xcc}},
{ // 54
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04},
nil,
[]byte{0xfc, 0xdb, 0x32, 0x91, 0xde, 0x21, 0xf0, 0xc0}},
{ // 55
[]byte{
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02},
nil,
[]byte{0x86, 0x9e, 0xfd, 0x7f, 0x9f, 0x26, 0x5a, 0x09}},
}
 
// Plaintext for use with Table A.3 tests
var tableA3Plaintext = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
// Table A.3 Values To Be Used for the Permutation Operation Known Answer Test
var tableA3Tests = []CryptTest{
{ // 0
[]byte{
0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31,
0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31,
0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31,
},
nil,
[]byte{0x88, 0xd5, 0x5e, 0x54, 0xf5, 0x4c, 0x97, 0xb4}},
{ // 1
[]byte{
0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
},
nil,
[]byte{0x0c, 0x0c, 0xc0, 0x0c, 0x83, 0xea, 0x48, 0xfd}},
{ // 2
[]byte{
0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20,
0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20,
0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20,
},
nil,
[]byte{0x83, 0xbc, 0x8e, 0xf3, 0xa6, 0x57, 0x01, 0x83}},
{ // 3
[]byte{
0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
},
nil,
[]byte{0xdf, 0x72, 0x5d, 0xca, 0xd9, 0x4e, 0xa2, 0xe9}},
{ // 4
[]byte{
0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01,
0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01,
0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01,
},
nil,
[]byte{0xe6, 0x52, 0xb5, 0x3b, 0x55, 0x0b, 0xe8, 0xb0}},
{ // 5
[]byte{
0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01,
0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01,
0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01,
},
nil,
[]byte{0xaf, 0x52, 0x71, 0x20, 0xc4, 0x85, 0xcb, 0xb0}},
{ // 6
[]byte{
0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01,
0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01,
0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01,
},
nil,
[]byte{0x0f, 0x04, 0xce, 0x39, 0x3d, 0xb9, 0x26, 0xd5}},
{ // 7
[]byte{
0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01,
0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01,
0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01,
},
nil,
[]byte{0xc9, 0xf0, 0x0f, 0xfc, 0x74, 0x07, 0x90, 0x67}},
{ // 8
[]byte{
0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01,
0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01,
0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01,
},
nil,
[]byte{0x7c, 0xfd, 0x82, 0xa5, 0x93, 0x25, 0x2b, 0x4e}},
{ // 9
[]byte{
0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01,
0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01,
0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01,
},
nil,
[]byte{0xcb, 0x49, 0xa2, 0xf9, 0xe9, 0x13, 0x63, 0xe3}},
{ // 10
[]byte{
0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40,
0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40,
0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40,
},
nil,
[]byte{0x00, 0xb5, 0x88, 0xbe, 0x70, 0xd2, 0x3f, 0x56}},
{ // 11
[]byte{
0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40,
0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40,
0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40,
},
nil,
[]byte{0x40, 0x6a, 0x9a, 0x6a, 0xb4, 0x33, 0x99, 0xae}},
{ // 12
[]byte{
0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01,
0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01,
0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01,
},
nil,
[]byte{0x6c, 0xb7, 0x73, 0x61, 0x1d, 0xca, 0x9a, 0xda}},
{ // 13
[]byte{
0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01,
0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01,
0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01,
},
nil,
[]byte{0x67, 0xfd, 0x21, 0xc1, 0x7d, 0xbb, 0x5d, 0x70}},
{ // 14
[]byte{
0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
},
nil,
[]byte{0x95, 0x92, 0xcb, 0x41, 0x10, 0x43, 0x07, 0x87}},
{ // 15
[]byte{
0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20,
0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20,
0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20,
},
nil,
[]byte{0xa6, 0xb7, 0xff, 0x68, 0xa3, 0x18, 0xdd, 0xd3}},
{ // 16
[]byte{
0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01,
0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01,
0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01,
},
nil,
[]byte{0x4d, 0x10, 0x21, 0x96, 0xc9, 0x14, 0xca, 0x16}},
{ // 17
[]byte{
0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01,
0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01,
0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01,
},
nil,
[]byte{0x2d, 0xfa, 0x9f, 0x45, 0x73, 0x59, 0x49, 0x65}},
{ // 18
[]byte{
0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01,
0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01,
0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01,
},
nil,
[]byte{0xb4, 0x66, 0x04, 0x81, 0x6c, 0x0e, 0x07, 0x74}},
{ // 19
[]byte{
0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01,
0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01,
0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01,
},
nil,
[]byte{0x6e, 0x7e, 0x62, 0x21, 0xa4, 0xf3, 0x4e, 0x87}},
{ // 20
[]byte{
0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01,
0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01,
0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01,
},
nil,
[]byte{0xaa, 0x85, 0xe7, 0x46, 0x43, 0x23, 0x31, 0x99}},
{ // 21
[]byte{
0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01,
0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01,
0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01,
},
nil,
[]byte{0x2e, 0x5a, 0x19, 0xdb, 0x4d, 0x19, 0x62, 0xd6}},
{ // 22
[]byte{
0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01,
0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01,
0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01,
},
nil,
[]byte{0x23, 0xa8, 0x66, 0xa8, 0x09, 0xd3, 0x08, 0x94}},
{ // 23
[]byte{
0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01,
0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01,
0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01,
},
nil,
[]byte{0xd8, 0x12, 0xd9, 0x61, 0xf0, 0x17, 0xd3, 0x20}},
{ // 24
[]byte{
0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b,
0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b,
0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b,
},
nil,
[]byte{0x05, 0x56, 0x05, 0x81, 0x6e, 0x58, 0x60, 0x8f}},
{ // 25
[]byte{
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01,
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01,
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01,
},
nil,
[]byte{0xab, 0xd8, 0x8e, 0x8b, 0x1b, 0x77, 0x16, 0xf1}},
{ // 26
[]byte{
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02,
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02,
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02,
},
nil,
[]byte{0x53, 0x7a, 0xc9, 0x5b, 0xe6, 0x9d, 0xa1, 0xe1}},
{ // 27
[]byte{
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08,
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08,
0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08,
},
nil,
[]byte{0xae, 0xd0, 0xf6, 0xae, 0x3c, 0x25, 0xcd, 0xd8}},
{ // 28
[]byte{
0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04,
0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04,
0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04,
},
nil,
[]byte{0xb3, 0xe3, 0x5a, 0x5e, 0xe5, 0x3e, 0x7b, 0x8d}},
{ // 29
[]byte{
0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04,
0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04,
0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04,
},
nil,
[]byte{0x61, 0xc7, 0x9c, 0x71, 0x92, 0x1a, 0x2e, 0xf8}},
{ // 30
[]byte{
0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01,
0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01,
0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01,
},
nil,
[]byte{0xe2, 0xf5, 0x72, 0x8f, 0x09, 0x95, 0x01, 0x3c}},
{ // 31
[]byte{
0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01,
0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01,
0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01,
},
nil,
[]byte{0x1a, 0xea, 0xc3, 0x9a, 0x61, 0xf0, 0xa4, 0x64}},
}
 
// Table A.4 Values To Be Used for the Substitution Table Known Answer Test
var tableA4Tests = []CryptTest{
{ // 0
[]byte{
0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57,
0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57,
0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57},
[]byte{0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42},
[]byte{0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b}},
{ // 1
[]byte{
0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e,
0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e,
0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e},
[]byte{0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda},
[]byte{0x7a, 0x38, 0x9d, 0x10, 0x35, 0x4b, 0xd2, 0x71}},
{ // 2
[]byte{
0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86,
0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86,
0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86},
[]byte{0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72},
[]byte{0x86, 0x8e, 0xbb, 0x51, 0xca, 0xb4, 0x59, 0x9a}},
{ // 3
[]byte{
0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e,
0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e,
0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e},
[]byte{0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a},
[]byte{0x71, 0x78, 0x87, 0x6e, 0x01, 0xf1, 0x9b, 0x2a}},
{ // 4
[]byte{
0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6,
0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6,
0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6},
[]byte{0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2},
[]byte{0xaf, 0x37, 0xfb, 0x42, 0x1f, 0x8c, 0x40, 0x95}},
{ // 5
[]byte{
0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce,
0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce,
0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce},
[]byte{0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a},
[]byte{0x86, 0xa5, 0x60, 0xf1, 0x0e, 0xc6, 0xd8, 0x5b}},
{ // 6
[]byte{
0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6,
0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6,
0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6},
[]byte{0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2},
[]byte{0x0c, 0xd3, 0xda, 0x02, 0x00, 0x21, 0xdc, 0x09}},
{ // 7
[]byte{
0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe,
0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe,
0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe},
[]byte{0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a},
[]byte{0xea, 0x67, 0x6b, 0x2c, 0xb7, 0xdb, 0x2b, 0x7a}},
{ // 8
[]byte{
0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16,
0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16,
0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16},
[]byte{0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
[]byte{0xdf, 0xd6, 0x4a, 0x81, 0x5c, 0xaf, 0x1a, 0x0f}},
{ // 9
[]byte{
0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f,
0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f,
0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f},
[]byte{0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a},
[]byte{0x5c, 0x51, 0x3c, 0x9c, 0x48, 0x86, 0xc0, 0x88}},
{ // 10
[]byte{
0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46,
0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46,
0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46},
[]byte{0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32},
[]byte{0x0a, 0x2a, 0xee, 0xae, 0x3f, 0xf4, 0xab, 0x77}},
{ // 11
[]byte{
0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e,
0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e,
0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e},
[]byte{0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca},
[]byte{0xef, 0x1b, 0xf0, 0x3e, 0x5d, 0xfa, 0x57, 0x5a}},
{ // 12
[]byte{
0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76},
[]byte{0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62},
[]byte{0x88, 0xbf, 0x0d, 0xb6, 0xd7, 0x0d, 0xee, 0x56}},
{ // 13
[]byte{
0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07,
0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07,
0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07},
[]byte{0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2},
[]byte{0xa1, 0xf9, 0x91, 0x55, 0x41, 0x02, 0x0b, 0x56}},
{ // 14
[]byte{
0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f,
0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f,
0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f},
[]byte{0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa},
[]byte{0x6f, 0xbf, 0x1c, 0xaf, 0xcf, 0xfd, 0x05, 0x56}},
{ // 15
[]byte{
0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7,
0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7,
0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7},
[]byte{0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92},
[]byte{0x2f, 0x22, 0xe4, 0x9b, 0xab, 0x7c, 0xa1, 0xac}},
{ // 16
[]byte{
0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf,
0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf,
0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf},
[]byte{0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a},
[]byte{0x5a, 0x6b, 0x61, 0x2c, 0xc2, 0x6c, 0xce, 0x4a}},
{ // 17
[]byte{
0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6,
0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6,
0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6},
[]byte{0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2},
[]byte{0x5f, 0x4c, 0x03, 0x8e, 0xd1, 0x2b, 0x2e, 0x41}},
{ // 18
[]byte{
0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef,
0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef,
0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef},
[]byte{0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a},
[]byte{0x63, 0xfa, 0xc0, 0xd0, 0x34, 0xd9, 0xf7, 0x93}},
}
 
// Use the known weak keys to test DES implementation
func TestWeakKeys(t *testing.T) {
for i, tt := range weakKeyTests {
var encrypt = func(in []byte) (out []byte) {
c, _ := NewCipher(tt.key)
out = make([]byte, len(in))
encryptBlock(c.subkeys[:], out, in)
return
}
 
// Encrypting twice with a DES weak
// key should reproduce the original input
result := encrypt(tt.in)
result = encrypt(result)
 
if !bytes.Equal(result, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, result, tt.in)
}
}
}
 
// Use the known semi-weak key pairs to test DES implementation
func TestSemiWeakKeyPairs(t *testing.T) {
for i, tt := range semiWeakKeyTests {
var encrypt = func(key, in []byte) (out []byte) {
c, _ := NewCipher(key)
out = make([]byte, len(in))
encryptBlock(c.subkeys[:], out, in)
return
}
 
// Encrypting with one member of the semi-weak pair
// and then encrypting the result with the other member
// should reproduce the original input.
result := encrypt(tt.key, tt.in)
result = encrypt(tt.out, result)
 
if !bytes.Equal(result, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, result, tt.in)
}
}
}
 
func TestDESEncryptBlock(t *testing.T) {
for i, tt := range encryptDESTests {
c, _ := NewCipher(tt.key)
out := make([]byte, len(tt.in))
encryptBlock(c.subkeys[:], out, tt.in)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
func TestDESDecryptBlock(t *testing.T) {
for i, tt := range encryptDESTests {
c, _ := NewCipher(tt.key)
plain := make([]byte, len(tt.in))
decryptBlock(c.subkeys[:], plain, tt.out)
 
if !bytes.Equal(plain, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
}
}
}
 
func TestEncryptTripleDES(t *testing.T) {
for i, tt := range encryptTripleDESTests {
c, _ := NewTripleDESCipher(tt.key)
out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
func TestDecryptTripleDES(t *testing.T) {
for i, tt := range encryptTripleDESTests {
c, _ := NewTripleDESCipher(tt.key)
 
plain := make([]byte, len(tt.in))
c.Decrypt(plain, tt.out)
 
if !bytes.Equal(plain, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
}
}
}
 
// Defined in Pub 800-20
func TestVariablePlaintextKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests {
c, _ := NewTripleDESCipher(tableA1Key)
 
out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
// Defined in Pub 800-20
func TestVariableCiphertextKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests {
c, _ := NewTripleDESCipher(tableA1Key)
 
plain := make([]byte, len(tt.out))
c.Decrypt(plain, tt.out)
 
if !bytes.Equal(plain, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
}
}
}
 
// Defined in Pub 800-20
// Encrypting the Table A.1 ciphertext with the
// 0x01... key produces the original plaintext
func TestInversePermutationKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests {
c, _ := NewTripleDESCipher(tableA1Key)
 
plain := make([]byte, len(tt.in))
c.Encrypt(plain, tt.out)
 
if !bytes.Equal(plain, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
}
}
}
 
// Defined in Pub 800-20
// Decrypting the Table A.1 plaintext with the
// 0x01... key produces the corresponding ciphertext
func TestInitialPermutationKnownAnswer(t *testing.T) {
for i, tt := range tableA1Tests {
c, _ := NewTripleDESCipher(tableA1Key)
 
out := make([]byte, len(tt.in))
c.Decrypt(out, tt.in)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
// Defined in Pub 800-20
func TestVariableKeyKnownAnswerEncrypt(t *testing.T) {
for i, tt := range tableA2Tests {
c, _ := NewTripleDESCipher(tt.key)
 
out := make([]byte, len(tableA2Plaintext))
c.Encrypt(out, tableA2Plaintext)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
// Defined in Pub 800-20
func TestVariableKeyKnownAnswerDecrypt(t *testing.T) {
for i, tt := range tableA2Tests {
c, _ := NewTripleDESCipher(tt.key)
 
out := make([]byte, len(tt.out))
c.Decrypt(out, tt.out)
 
if !bytes.Equal(out, tableA2Plaintext) {
t.Errorf("#%d: result: %x want: %x", i, out, tableA2Plaintext)
}
}
}
 
// Defined in Pub 800-20
func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) {
for i, tt := range tableA3Tests {
c, _ := NewTripleDESCipher(tt.key)
 
out := make([]byte, len(tableA3Plaintext))
c.Encrypt(out, tableA3Plaintext)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
// Defined in Pub 800-20
func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) {
for i, tt := range tableA3Tests {
c, _ := NewTripleDESCipher(tt.key)
 
out := make([]byte, len(tt.out))
c.Decrypt(out, tt.out)
 
if !bytes.Equal(out, tableA3Plaintext) {
t.Errorf("#%d: result: %x want: %x", i, out, tableA3Plaintext)
}
}
}
 
// Defined in Pub 800-20
func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) {
for i, tt := range tableA4Tests {
c, _ := NewTripleDESCipher(tt.key)
 
out := make([]byte, len(tt.in))
c.Encrypt(out, tt.in)
 
if !bytes.Equal(out, tt.out) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
}
}
}
 
// Defined in Pub 800-20
func TestSubstitutionTableKnownAnswerDecrypt(t *testing.T) {
for i, tt := range tableA4Tests {
c, _ := NewTripleDESCipher(tt.key)
 
out := make([]byte, len(tt.out))
c.Decrypt(out, tt.out)
 
if !bytes.Equal(out, tt.in) {
t.Errorf("#%d: result: %x want: %x", i, out, tt.in)
}
}
}
/des/cipher.go
0,0 → 1,100
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package des
 
import "strconv"
 
// The DES block size in bytes.
const BlockSize = 8
 
type KeySizeError int
 
func (k KeySizeError) Error() string {
return "crypto/des: invalid key size " + strconv.Itoa(int(k))
}
 
// Cipher is an instance of DES encryption.
type Cipher struct {
subkeys [16]uint64
}
 
// NewCipher creates and returns a new Cipher.
func NewCipher(key []byte) (*Cipher, error) {
if len(key) != 8 {
return nil, KeySizeError(len(key))
}
 
c := new(Cipher)
c.generateSubkeys(key)
return c, nil
}
 
// BlockSize returns the DES block size, 8 bytes.
func (c *Cipher) BlockSize() int { return BlockSize }
 
// Encrypt encrypts the 8-byte buffer src and stores the result in dst.
// Note that for amounts of data larger than a block,
// it is not safe to just call Encrypt on successive blocks;
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) }
 
// Decrypt decrypts the 8-byte buffer src and stores the result in dst.
func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) }
 
// Reset zeros the key data, so that it will no longer
// appear in the process's memory.
func (c *Cipher) Reset() {
for i := 0; i < len(c.subkeys); i++ {
c.subkeys[i] = 0
}
}
 
// A TripleDESCipher is an instance of TripleDES encryption.
type TripleDESCipher struct {
cipher1, cipher2, cipher3 Cipher
}
 
// NewCipher creates and returns a new Cipher.
func NewTripleDESCipher(key []byte) (*TripleDESCipher, error) {
if len(key) != 24 {
return nil, KeySizeError(len(key))
}
 
c := new(TripleDESCipher)
c.cipher1.generateSubkeys(key[:8])
c.cipher2.generateSubkeys(key[8:16])
c.cipher3.generateSubkeys(key[16:])
return c, nil
}
 
// BlockSize returns the TripleDES block size, 8 bytes.
// It is necessary to satisfy the Block interface in the
// package "crypto/cipher".
func (c *TripleDESCipher) BlockSize() int { return BlockSize }
 
// Encrypts the 8-byte buffer src and stores the result in dst.
// Note that for amounts of data larger than a block,
// it is not safe to just call Encrypt on successive blocks;
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
func (c *TripleDESCipher) Encrypt(dst, src []byte) {
c.cipher1.Encrypt(dst, src)
c.cipher2.Decrypt(dst, dst)
c.cipher3.Encrypt(dst, dst)
}
 
// Decrypts the 8-byte buffer src and stores the result in dst.
func (c *TripleDESCipher) Decrypt(dst, src []byte) {
c.cipher3.Decrypt(dst, src)
c.cipher2.Encrypt(dst, dst)
c.cipher1.Decrypt(dst, dst)
}
 
// Reset zeros the key data, so that it will no longer
// appear in the process's memory.
func (c *TripleDESCipher) Reset() {
c.cipher1.Reset()
c.cipher2.Reset()
c.cipher3.Reset()
}
/des/block.go
0,0 → 1,98
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package des
 
import (
"encoding/binary"
)
 
func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) {
b := binary.BigEndian.Uint64(src)
b = permuteBlock(b, initialPermutation[:])
left, right := uint32(b>>32), uint32(b)
 
var subkey uint64
for i := 0; i < 16; i++ {
if decrypt {
subkey = subkeys[15-i]
} else {
subkey = subkeys[i]
}
 
left, right = right, left^feistel(right, subkey)
}
// switch left & right and perform final permutation
preOutput := (uint64(right) << 32) | uint64(left)
binary.BigEndian.PutUint64(dst, permuteBlock(preOutput, finalPermutation[:]))
}
 
// Encrypt one block from src into dst, using the subkeys.
func encryptBlock(subkeys []uint64, dst, src []byte) {
cryptBlock(subkeys, dst, src, false)
}
 
// Decrypt one block from src into dst, using the subkeys.
func decryptBlock(subkeys []uint64, dst, src []byte) {
cryptBlock(subkeys, dst, src, true)
}
 
// DES Feistel function
func feistel(right uint32, key uint64) (result uint32) {
sBoxLocations := key ^ permuteBlock(uint64(right), expansionFunction[:])
var sBoxResult uint32
for i := uint8(0); i < 8; i++ {
sBoxLocation := uint8(sBoxLocations>>42) & 0x3f
sBoxLocations <<= 6
// row determined by 1st and 6th bit
row := (sBoxLocation & 0x1) | ((sBoxLocation & 0x20) >> 4)
// column is middle four bits
column := (sBoxLocation >> 1) & 0xf
sBoxResult |= uint32(sBoxes[i][row][column]) << (4 * (7 - i))
}
return uint32(permuteBlock(uint64(sBoxResult), permutationFunction[:]))
}
 
// general purpose function to perform DES block permutations
func permuteBlock(src uint64, permutation []uint8) (block uint64) {
for position, n := range permutation {
bit := (src >> n) & 1
block |= bit << uint((len(permutation)-1)-position)
}
return
}
 
// creates 16 28-bit blocks rotated according
// to the rotation schedule
func ksRotate(in uint32) (out []uint32) {
out = make([]uint32, 16)
last := in
for i := 0; i < 16; i++ {
// 28-bit circular left shift
left := (last << (4 + ksRotations[i])) >> 4
right := (last << 4) >> (32 - ksRotations[i])
out[i] = left | right
last = out[i]
}
return
}
 
// creates 16 56-bit subkeys from the original key
func (c *Cipher) generateSubkeys(keyBytes []byte) {
// apply PC1 permutation to key
key := binary.BigEndian.Uint64(keyBytes)
permutedKey := permuteBlock(key, permutedChoice1[:])
 
// rotate halves of permuted key according to the rotation schedule
leftRotations := ksRotate(uint32(permutedKey >> 28))
rightRotations := ksRotate(uint32(permutedKey<<4) >> 4)
 
// generate subkeys
for i := 0; i < 16; i++ {
// combine halves to form 56-bit input to PC2
pc2Input := uint64(leftRotations[i])<<28 | uint64(rightRotations[i])
// apply PC2 permutation to 7 byte input
c.subkeys[i] = permuteBlock(pc2Input, permutedChoice2[:])
}
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.