Commit cdd7e025 authored by Adam Langley's avatar Adam Langley

crypto/...: more fixes for bug 2841

1) Remove the Reset() member in crypto/aes and crypto/des (and
   document the change).
2) Turn several empty error structures into vars. Any remaining error
   structures are either non-empty, or will probably become so in the
   future.
3) Implement SetWriteDeadline for TLS sockets. At the moment, the TLS
   status cannot be reused after a Write error, which is probably fine
   for most uses.
4) Make crypto/aes and crypto/des return a cipher.Block.

R=rsc, r
CC=golang-dev
https://golang.org/cl/5625045
parent a52fb458
This diff is collapsed.
This diff is collapsed.
...@@ -4,13 +4,16 @@ ...@@ -4,13 +4,16 @@
package aes package aes
import "strconv" import (
"crypto/cipher"
"strconv"
)
// The AES block size in bytes. // The AES block size in bytes.
const BlockSize = 16 const BlockSize = 16
// A Cipher is an instance of AES encryption using a particular key. // A cipher is an instance of AES encryption using a particular key.
type Cipher struct { type aesCipher struct {
enc []uint32 enc []uint32
dec []uint32 dec []uint32
} }
...@@ -21,11 +24,11 @@ func (k KeySizeError) Error() string { ...@@ -21,11 +24,11 @@ func (k KeySizeError) Error() string {
return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) return "crypto/aes: invalid key size " + strconv.Itoa(int(k))
} }
// NewCipher creates and returns a new Cipher. // NewCipher creates and returns a new cipher.Block.
// The key argument should be the AES key, // The key argument should be the AES key,
// either 16, 24, or 32 bytes to select // either 16, 24, or 32 bytes to select
// AES-128, AES-192, or AES-256. // AES-128, AES-192, or AES-256.
func NewCipher(key []byte) (*Cipher, error) { func NewCipher(key []byte) (cipher.Block, error) {
k := len(key) k := len(key)
switch k { switch k {
default: default:
...@@ -35,34 +38,13 @@ func NewCipher(key []byte) (*Cipher, error) { ...@@ -35,34 +38,13 @@ func NewCipher(key []byte) (*Cipher, error) {
} }
n := k + 28 n := k + 28
c := &Cipher{make([]uint32, n), make([]uint32, n)} c := &aesCipher{make([]uint32, n), make([]uint32, n)}
expandKey(key, c.enc, c.dec) expandKey(key, c.enc, c.dec)
return c, nil return c, nil
} }
// BlockSize returns the AES block size, 16 bytes. func (c *aesCipher) BlockSize() int { return BlockSize }
// 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 func (c *aesCipher) Encrypt(dst, src []byte) { encryptBlock(c.enc, dst, 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.enc, dst, src) }
// Decrypt decrypts the 16-byte buffer src using the key k func (c *aesCipher) Decrypt(dst, src []byte) { decryptBlock(c.dec, dst, src) }
// 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
}
}
...@@ -8,11 +8,12 @@ ...@@ -8,11 +8,12 @@
// Special Publication 800-38A, ``Recommendation for Block Cipher // Special Publication 800-38A, ``Recommendation for Block Cipher
// Modes of Operation,'' 2001 Edition, pp. 24-29. // Modes of Operation,'' 2001 Edition, pp. 24-29.
package cipher package cipher_test
import ( import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher"
"testing" "testing"
) )
...@@ -72,14 +73,14 @@ func TestCBC_AES(t *testing.T) { ...@@ -72,14 +73,14 @@ func TestCBC_AES(t *testing.T) {
continue continue
} }
encrypter := NewCBCEncrypter(c, tt.iv) encrypter := cipher.NewCBCEncrypter(c, tt.iv)
d := make([]byte, len(tt.in)) d := make([]byte, len(tt.in))
encrypter.CryptBlocks(d, tt.in) encrypter.CryptBlocks(d, tt.in)
if !bytes.Equal(tt.out, d) { if !bytes.Equal(tt.out, d) {
t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test, d, tt.out) t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test, d, tt.out)
} }
decrypter := NewCBCDecrypter(c, tt.iv) decrypter := cipher.NewCBCDecrypter(c, tt.iv)
p := make([]byte, len(d)) p := make([]byte, len(d))
decrypter.CryptBlocks(p, d) decrypter.CryptBlocks(p, d)
if !bytes.Equal(tt.in, p) { if !bytes.Equal(tt.in, p) {
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package cipher package cipher_test
import ( import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher"
"crypto/rand" "crypto/rand"
"testing" "testing"
) )
...@@ -21,11 +22,11 @@ func TestCFB(t *testing.T) { ...@@ -21,11 +22,11 @@ func TestCFB(t *testing.T) {
plaintext := []byte("this is the plaintext") plaintext := []byte("this is the plaintext")
iv := make([]byte, block.BlockSize()) iv := make([]byte, block.BlockSize())
rand.Reader.Read(iv) rand.Reader.Read(iv)
cfb := NewCFBEncrypter(block, iv) cfb := cipher.NewCFBEncrypter(block, iv)
ciphertext := make([]byte, len(plaintext)) ciphertext := make([]byte, len(plaintext))
cfb.XORKeyStream(ciphertext, plaintext) cfb.XORKeyStream(ciphertext, plaintext)
cfbdec := NewCFBDecrypter(block, iv) cfbdec := cipher.NewCFBDecrypter(block, iv)
plaintextCopy := make([]byte, len(plaintext)) plaintextCopy := make([]byte, len(plaintext))
cfbdec.XORKeyStream(plaintextCopy, ciphertext) cfbdec.XORKeyStream(plaintextCopy, ciphertext)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package cipher package cipher_test
// Common values for tests. // Common values for tests.
......
...@@ -8,11 +8,12 @@ ...@@ -8,11 +8,12 @@
// Special Publication 800-38A, ``Recommendation for Block Cipher // Special Publication 800-38A, ``Recommendation for Block Cipher
// Modes of Operation,'' 2001 Edition, pp. 55-58. // Modes of Operation,'' 2001 Edition, pp. 55-58.
package cipher package cipher_test
import ( import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher"
"testing" "testing"
) )
...@@ -76,7 +77,7 @@ func TestCTR_AES(t *testing.T) { ...@@ -76,7 +77,7 @@ func TestCTR_AES(t *testing.T) {
for j := 0; j <= 5; j += 5 { for j := 0; j <= 5; j += 5 {
in := tt.in[0 : len(tt.in)-j] in := tt.in[0 : len(tt.in)-j]
ctr := NewCTR(c, tt.iv) ctr := cipher.NewCTR(c, tt.iv)
encrypted := make([]byte, len(in)) encrypted := make([]byte, len(in))
ctr.XORKeyStream(encrypted, in) ctr.XORKeyStream(encrypted, in)
if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) { if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) {
...@@ -86,7 +87,7 @@ func TestCTR_AES(t *testing.T) { ...@@ -86,7 +87,7 @@ func TestCTR_AES(t *testing.T) {
for j := 0; j <= 7; j += 7 { for j := 0; j <= 7; j += 7 {
in := tt.out[0 : len(tt.out)-j] in := tt.out[0 : len(tt.out)-j]
ctr := NewCTR(c, tt.iv) ctr := cipher.NewCTR(c, tt.iv)
plain := make([]byte, len(in)) plain := make([]byte, len(in))
ctr.XORKeyStream(plain, in) ctr.XORKeyStream(plain, in)
if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) { if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) {
......
...@@ -8,11 +8,12 @@ ...@@ -8,11 +8,12 @@
// Special Publication 800-38A, ``Recommendation for Block Cipher // Special Publication 800-38A, ``Recommendation for Block Cipher
// Modes of Operation,'' 2001 Edition, pp. 52-55. // Modes of Operation,'' 2001 Edition, pp. 52-55.
package cipher package cipher_test
import ( import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher"
"testing" "testing"
) )
...@@ -76,7 +77,7 @@ func TestOFB(t *testing.T) { ...@@ -76,7 +77,7 @@ func TestOFB(t *testing.T) {
for j := 0; j <= 5; j += 5 { for j := 0; j <= 5; j += 5 {
plaintext := tt.in[0 : len(tt.in)-j] plaintext := tt.in[0 : len(tt.in)-j]
ofb := NewOFB(c, tt.iv) ofb := cipher.NewOFB(c, tt.iv)
ciphertext := make([]byte, len(plaintext)) ciphertext := make([]byte, len(plaintext))
ofb.XORKeyStream(ciphertext, plaintext) ofb.XORKeyStream(ciphertext, plaintext)
if !bytes.Equal(ciphertext, tt.out[:len(plaintext)]) { if !bytes.Equal(ciphertext, tt.out[:len(plaintext)]) {
...@@ -86,7 +87,7 @@ func TestOFB(t *testing.T) { ...@@ -86,7 +87,7 @@ func TestOFB(t *testing.T) {
for j := 0; j <= 5; j += 5 { for j := 0; j <= 5; j += 5 {
ciphertext := tt.out[0 : len(tt.in)-j] ciphertext := tt.out[0 : len(tt.in)-j]
ofb := NewOFB(c, tt.iv) ofb := cipher.NewOFB(c, tt.iv)
plaintext := make([]byte, len(ciphertext)) plaintext := make([]byte, len(ciphertext))
ofb.XORKeyStream(plaintext, ciphertext) ofb.XORKeyStream(plaintext, ciphertext)
if !bytes.Equal(plaintext, tt.in[:len(ciphertext)]) { if !bytes.Equal(plaintext, tt.in[:len(ciphertext)]) {
......
...@@ -79,7 +79,7 @@ func ksRotate(in uint32) (out []uint32) { ...@@ -79,7 +79,7 @@ func ksRotate(in uint32) (out []uint32) {
} }
// creates 16 56-bit subkeys from the original key // creates 16 56-bit subkeys from the original key
func (c *Cipher) generateSubkeys(keyBytes []byte) { func (c *desCipher) generateSubkeys(keyBytes []byte) {
// apply PC1 permutation to key // apply PC1 permutation to key
key := binary.BigEndian.Uint64(keyBytes) key := binary.BigEndian.Uint64(keyBytes)
permutedKey := permuteBlock(key, permutedChoice1[:]) permutedKey := permuteBlock(key, permutedChoice1[:])
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package des package des
import "strconv" import (
"crypto/cipher"
"strconv"
)
// The DES block size in bytes. // The DES block size in bytes.
const BlockSize = 8 const BlockSize = 8
...@@ -15,86 +18,56 @@ func (k KeySizeError) Error() string { ...@@ -15,86 +18,56 @@ func (k KeySizeError) Error() string {
return "crypto/des: invalid key size " + strconv.Itoa(int(k)) return "crypto/des: invalid key size " + strconv.Itoa(int(k))
} }
// Cipher is an instance of DES encryption. // desCipher is an instance of DES encryption.
type Cipher struct { type desCipher struct {
subkeys [16]uint64 subkeys [16]uint64
} }
// NewCipher creates and returns a new Cipher. // NewCipher creates and returns a new cipher.Block.
func NewCipher(key []byte) (*Cipher, error) { func NewCipher(key []byte) (cipher.Block, error) {
if len(key) != 8 { if len(key) != 8 {
return nil, KeySizeError(len(key)) return nil, KeySizeError(len(key))
} }
c := new(Cipher) c := new(desCipher)
c.generateSubkeys(key) c.generateSubkeys(key)
return c, nil return c, nil
} }
// BlockSize returns the DES block size, 8 bytes. func (c *desCipher) BlockSize() int { return BlockSize }
func (c *Cipher) BlockSize() int { return BlockSize }
// Encrypt encrypts the 8-byte buffer src and stores the result in dst. func (c *desCipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) }
// 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 *desCipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) }
func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) }
// Reset zeros the key data, so that it will no longer // A tripleDESCipher is an instance of TripleDES encryption.
// appear in the process's memory. type tripleDESCipher struct {
func (c *Cipher) Reset() { cipher1, cipher2, cipher3 desCipher
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. // NewTripleDESCipher creates and returns a new cipher.Block.
func NewTripleDESCipher(key []byte) (*TripleDESCipher, error) { func NewTripleDESCipher(key []byte) (cipher.Block, error) {
if len(key) != 24 { if len(key) != 24 {
return nil, KeySizeError(len(key)) return nil, KeySizeError(len(key))
} }
c := new(TripleDESCipher) c := new(tripleDESCipher)
c.cipher1.generateSubkeys(key[:8]) c.cipher1.generateSubkeys(key[:8])
c.cipher2.generateSubkeys(key[8:16]) c.cipher2.generateSubkeys(key[8:16])
c.cipher3.generateSubkeys(key[16:]) c.cipher3.generateSubkeys(key[16:])
return c, nil return c, nil
} }
// BlockSize returns the TripleDES block size, 8 bytes. func (c *tripleDESCipher) BlockSize() int { return BlockSize }
// 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. func (c *tripleDESCipher) Encrypt(dst, src []byte) {
// 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.cipher1.Encrypt(dst, src)
c.cipher2.Decrypt(dst, dst) c.cipher2.Decrypt(dst, dst)
c.cipher3.Encrypt(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) {
func (c *TripleDESCipher) Decrypt(dst, src []byte) {
c.cipher3.Decrypt(dst, src) c.cipher3.Decrypt(dst, src)
c.cipher2.Encrypt(dst, dst) c.cipher2.Encrypt(dst, dst)
c.cipher1.Decrypt(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()
}
...@@ -1260,11 +1260,19 @@ var tableA4Tests = []CryptTest{ ...@@ -1260,11 +1260,19 @@ var tableA4Tests = []CryptTest{
[]byte{0x63, 0xfa, 0xc0, 0xd0, 0x34, 0xd9, 0xf7, 0x93}}, []byte{0x63, 0xfa, 0xc0, 0xd0, 0x34, 0xd9, 0xf7, 0x93}},
} }
func newCipher(key []byte) *desCipher {
c, err := NewCipher(key)
if err != nil {
panic("NewCipher failed: " + err.Error())
}
return c.(*desCipher)
}
// Use the known weak keys to test DES implementation // Use the known weak keys to test DES implementation
func TestWeakKeys(t *testing.T) { func TestWeakKeys(t *testing.T) {
for i, tt := range weakKeyTests { for i, tt := range weakKeyTests {
var encrypt = func(in []byte) (out []byte) { var encrypt = func(in []byte) (out []byte) {
c, _ := NewCipher(tt.key) c := newCipher(tt.key)
out = make([]byte, len(in)) out = make([]byte, len(in))
encryptBlock(c.subkeys[:], out, in) encryptBlock(c.subkeys[:], out, in)
return return
...@@ -1285,7 +1293,7 @@ func TestWeakKeys(t *testing.T) { ...@@ -1285,7 +1293,7 @@ func TestWeakKeys(t *testing.T) {
func TestSemiWeakKeyPairs(t *testing.T) { func TestSemiWeakKeyPairs(t *testing.T) {
for i, tt := range semiWeakKeyTests { for i, tt := range semiWeakKeyTests {
var encrypt = func(key, in []byte) (out []byte) { var encrypt = func(key, in []byte) (out []byte) {
c, _ := NewCipher(key) c := newCipher(key)
out = make([]byte, len(in)) out = make([]byte, len(in))
encryptBlock(c.subkeys[:], out, in) encryptBlock(c.subkeys[:], out, in)
return return
...@@ -1305,7 +1313,7 @@ func TestSemiWeakKeyPairs(t *testing.T) { ...@@ -1305,7 +1313,7 @@ func TestSemiWeakKeyPairs(t *testing.T) {
func TestDESEncryptBlock(t *testing.T) { func TestDESEncryptBlock(t *testing.T) {
for i, tt := range encryptDESTests { for i, tt := range encryptDESTests {
c, _ := NewCipher(tt.key) c := newCipher(tt.key)
out := make([]byte, len(tt.in)) out := make([]byte, len(tt.in))
encryptBlock(c.subkeys[:], out, tt.in) encryptBlock(c.subkeys[:], out, tt.in)
...@@ -1317,7 +1325,7 @@ func TestDESEncryptBlock(t *testing.T) { ...@@ -1317,7 +1325,7 @@ func TestDESEncryptBlock(t *testing.T) {
func TestDESDecryptBlock(t *testing.T) { func TestDESDecryptBlock(t *testing.T) {
for i, tt := range encryptDESTests { for i, tt := range encryptDESTests {
c, _ := NewCipher(tt.key) c := newCipher(tt.key)
plain := make([]byte, len(tt.in)) plain := make([]byte, len(tt.in))
decryptBlock(c.subkeys[:], plain, tt.out) decryptBlock(c.subkeys[:], plain, tt.out)
......
...@@ -29,17 +29,11 @@ type PrivateKey struct { ...@@ -29,17 +29,11 @@ type PrivateKey struct {
X *big.Int 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. // 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 // 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, // less so. Thus, when using keys which may have been generated by other code,
// this error must be handled. // this error must be handled.
var ErrInvalidPublicKey error = invalidPublicKeyError(0) var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")
// ParameterSizes is a enumeration of the acceptable bit lengths of the primes // 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. // in a set of DSA parameters. See FIPS 186-3, section 4.2.
......
...@@ -12,6 +12,7 @@ package rand ...@@ -12,6 +12,7 @@ package rand
import ( import (
"bufio" "bufio"
"crypto/aes" "crypto/aes"
"crypto/cipher"
"io" "io"
"os" "os"
"sync" "sync"
...@@ -66,7 +67,7 @@ func newReader(entropy io.Reader) io.Reader { ...@@ -66,7 +67,7 @@ func newReader(entropy io.Reader) io.Reader {
type reader struct { type reader struct {
mu sync.Mutex mu sync.Mutex
budget int // number of bytes that can be generated budget int // number of bytes that can be generated
cipher *aes.Cipher cipher cipher.Block
entropy io.Reader entropy io.Reader
time, seed, dst, key [aes.BlockSize]byte time, seed, dst, key [aes.BlockSize]byte
} }
......
...@@ -21,7 +21,7 @@ import ( ...@@ -21,7 +21,7 @@ import (
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error) { func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error) {
k := (pub.N.BitLen() + 7) / 8 k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-11 { if len(msg) > k-11 {
err = MessageTooLongError{} err = ErrMessageTooLong
return return
} }
...@@ -47,7 +47,7 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er ...@@ -47,7 +47,7 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error) { func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error) {
valid, out, err := decryptPKCS1v15(rand, priv, ciphertext) valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
if err == nil && valid == 0 { if err == nil && valid == 0 {
err = DecryptionError{} err = ErrDecryption
} }
return return
...@@ -69,7 +69,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [ ...@@ -69,7 +69,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) { func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
k := (priv.N.BitLen() + 7) / 8 k := (priv.N.BitLen() + 7) / 8
if k-(len(key)+3+8) < 0 { if k-(len(key)+3+8) < 0 {
err = DecryptionError{} err = ErrDecryption
return return
} }
...@@ -86,7 +86,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by ...@@ -86,7 +86,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by
func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, msg []byte, err error) { func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, msg []byte, err error) {
k := (priv.N.BitLen() + 7) / 8 k := (priv.N.BitLen() + 7) / 8
if k < 11 { if k < 11 {
err = DecryptionError{} err = ErrDecryption
return return
} }
...@@ -170,7 +170,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b ...@@ -170,7 +170,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
tLen := len(prefix) + hashLen tLen := len(prefix) + hashLen
k := (priv.N.BitLen() + 7) / 8 k := (priv.N.BitLen() + 7) / 8
if k < tLen+11 { if k < tLen+11 {
return nil, MessageTooLongError{} return nil, ErrMessageTooLong
} }
// EM = 0x00 || 0x01 || PS || 0x00 || T // EM = 0x00 || 0x01 || PS || 0x00 || T
...@@ -203,7 +203,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) ...@@ -203,7 +203,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte)
tLen := len(prefix) + hashLen tLen := len(prefix) + hashLen
k := (pub.N.BitLen() + 7) / 8 k := (pub.N.BitLen() + 7) / 8
if k < tLen+11 { if k < tLen+11 {
err = VerificationError{} err = ErrVerification
return return
} }
...@@ -223,7 +223,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) ...@@ -223,7 +223,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte)
} }
if ok != 1 { if ok != 1 {
return VerificationError{} return ErrVerification
} }
return nil return nil
......
...@@ -206,13 +206,9 @@ func mgf1XOR(out []byte, hash hash.Hash, seed []byte) { ...@@ -206,13 +206,9 @@ func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
} }
} }
// MessageTooLongError is returned when attempting to encrypt a message which // ErrMessageTooLong is returned when attempting to encrypt a message which is
// is too large for the size of the public key. // too large for the size of the public key.
type MessageTooLongError struct{} var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")
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 { func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
e := big.NewInt(int64(pub.E)) e := big.NewInt(int64(pub.E))
...@@ -227,7 +223,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l ...@@ -227,7 +223,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
hash.Reset() hash.Reset()
k := (pub.N.BitLen() + 7) / 8 k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-2*hash.Size()-2 { if len(msg) > k-2*hash.Size()-2 {
err = MessageTooLongError{} err = ErrMessageTooLong
return return
} }
...@@ -266,17 +262,13 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l ...@@ -266,17 +262,13 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
return return
} }
// A DecryptionError represents a failure to decrypt a message. // ErrDecryption represents a failure to decrypt a message.
// It is deliberately vague to avoid adaptive attacks. // It is deliberately vague to avoid adaptive attacks.
type DecryptionError struct{} var ErrDecryption = errors.New("crypto/rsa: decryption error")
func (DecryptionError) Error() string { return "RSA decryption error" } // ErrVerification represents a failure to verify a signature.
// A VerificationError represents a failure to verify a signature.
// It is deliberately vague to avoid adaptive attacks. // It is deliberately vague to avoid adaptive attacks.
type VerificationError struct{} var ErrVerification = errors.New("crypto/rsa: verification error")
func (VerificationError) Error() string { return "RSA verification error" }
// modInverse returns ia, the inverse of a in the multiplicative group of prime // 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). // order n. It requires that a be a member of the group (i.e. less than n).
...@@ -338,7 +330,7 @@ func (priv *PrivateKey) Precompute() { ...@@ -338,7 +330,7 @@ func (priv *PrivateKey) Precompute() {
func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) { func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
// TODO(agl): can we get away with reusing blinds? // TODO(agl): can we get away with reusing blinds?
if c.Cmp(priv.N) > 0 { if c.Cmp(priv.N) > 0 {
err = DecryptionError{} err = ErrDecryption
return return
} }
...@@ -417,7 +409,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext ...@@ -417,7 +409,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
k := (priv.N.BitLen() + 7) / 8 k := (priv.N.BitLen() + 7) / 8
if len(ciphertext) > k || if len(ciphertext) > k ||
k < hash.Size()*2+2 { k < hash.Size()*2+2 {
err = DecryptionError{} err = ErrDecryption
return return
} }
...@@ -473,7 +465,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext ...@@ -473,7 +465,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
} }
if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 { if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
err = DecryptionError{} err = ErrDecryption
return return
} }
......
...@@ -87,9 +87,9 @@ func (c *Conn) RemoteAddr() net.Addr { ...@@ -87,9 +87,9 @@ func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr() return c.conn.RemoteAddr()
} }
// SetDeadline sets the read deadline associated with the connection. // SetDeadline sets the read and write deadlines associated with the connection.
// There is no write deadline. // A zero value for t means Read and Write will not time out.
// A zero value for t means Read will not time out. // After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
func (c *Conn) SetDeadline(t time.Time) error { func (c *Conn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t) return c.conn.SetDeadline(t)
} }
...@@ -100,10 +100,11 @@ func (c *Conn) SetReadDeadline(t time.Time) error { ...@@ -100,10 +100,11 @@ func (c *Conn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t) return c.conn.SetReadDeadline(t)
} }
// SetWriteDeadline exists to satisfy the net.Conn interface // SetWriteDeadline sets the write deadline on the underlying conneciton.
// but is not implemented by TLS. It always returns an error. // A zero value for t means Write will not time out.
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
func (c *Conn) SetWriteDeadline(t time.Time) error { func (c *Conn) SetWriteDeadline(t time.Time) error {
return errors.New("TLS does not support SetWriteDeadline") return c.conn.SetWriteDeadline(t)
} }
// A halfConn represents one direction of the record layer // A halfConn represents one direction of the record layer
...@@ -726,9 +727,13 @@ func (c *Conn) readHandshake() (interface{}, error) { ...@@ -726,9 +727,13 @@ func (c *Conn) readHandshake() (interface{}, error) {
} }
// Write writes data to the connection. // Write writes data to the connection.
func (c *Conn) Write(b []byte) (n int, err error) { func (c *Conn) Write(b []byte) (int, error) {
if err = c.Handshake(); err != nil { if c.err != nil {
return return 0, c.err
}
if c.err = c.Handshake(); c.err != nil {
return 0, c.err
} }
c.out.Lock() c.out.Lock()
...@@ -737,10 +742,10 @@ func (c *Conn) Write(b []byte) (n int, err error) { ...@@ -737,10 +742,10 @@ func (c *Conn) Write(b []byte) (n int, err error) {
if !c.handshakeComplete { if !c.handshakeComplete {
return 0, alertInternalError return 0, alertInternalError
} }
if c.err != nil {
return 0, c.err var n int
} n, c.err = c.writeRecord(recordTypeApplicationData, b)
return c.writeRecord(recordTypeApplicationData, b) return n, c.err
} }
// Read can be made to time out and return a net.Error with Timeout() == true // Read can be made to time out and return a net.Error with Timeout() == true
......
...@@ -327,13 +327,9 @@ type Certificate struct { ...@@ -327,13 +327,9 @@ type Certificate struct {
PolicyIdentifiers []asn1.ObjectIdentifier PolicyIdentifiers []asn1.ObjectIdentifier
} }
// UnsupportedAlgorithmError results from attempting to perform an operation // ErrUnsupportedAlgorithm results from attempting to perform an operation that
// that involves algorithms that are not currently implemented. // involves algorithms that are not currently implemented.
type UnsupportedAlgorithmError struct{} var ErrUnsupportedAlgorithm = errors.New("crypto/x509: cannot verify signature: algorithm unimplemented")
func (UnsupportedAlgorithmError) Error() string {
return "cannot verify signature: algorithm unimplemented"
}
// ConstraintViolationError results when a requested usage is not permitted by // ConstraintViolationError results when a requested usage is not permitted by
// a certificate. For example: checking a signature when the public key isn't a // a certificate. For example: checking a signature when the public key isn't a
...@@ -341,7 +337,7 @@ func (UnsupportedAlgorithmError) Error() string { ...@@ -341,7 +337,7 @@ func (UnsupportedAlgorithmError) Error() string {
type ConstraintViolationError struct{} type ConstraintViolationError struct{}
func (ConstraintViolationError) Error() string { func (ConstraintViolationError) Error() string {
return "invalid signature: parent certificate cannot sign this kind of certificate" return "crypto/x509: invalid signature: parent certificate cannot sign this kind of certificate"
} }
func (c *Certificate) Equal(other *Certificate) bool { func (c *Certificate) Equal(other *Certificate) bool {
...@@ -366,7 +362,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) { ...@@ -366,7 +362,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
} }
if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm { if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
return UnsupportedAlgorithmError{} return ErrUnsupportedAlgorithm
} }
// TODO(agl): don't ignore the path length constraint. // TODO(agl): don't ignore the path length constraint.
...@@ -389,12 +385,12 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature ...@@ -389,12 +385,12 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature
case SHA512WithRSA: case SHA512WithRSA:
hashType = crypto.SHA512 hashType = crypto.SHA512
default: default:
return UnsupportedAlgorithmError{} return ErrUnsupportedAlgorithm
} }
h := hashType.New() h := hashType.New()
if h == nil { if h == nil {
return UnsupportedAlgorithmError{} return ErrUnsupportedAlgorithm
} }
h.Write(signed) h.Write(signed)
...@@ -416,7 +412,7 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature ...@@ -416,7 +412,7 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature
} }
return return
} }
return UnsupportedAlgorithmError{} return ErrUnsupportedAlgorithm
} }
// CheckCRLSignature checks that the signature in crl is from c. // CheckCRLSignature checks that the signature in crl is from c.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment