mirror of
https://github.com/golang/go
synced 2024-11-21 19:14:44 -07:00
crypto/rsa: reject PublicKey.E if it won't fit in a 32-bit int
Right now we only have 32-bit ints so that's a no-op. Took the opportunity to check for some other invalid values too. Suggestions for additions or modifications welcome. R=agl CC=golang-dev https://golang.org/cl/6493112
This commit is contained in:
parent
6ee91ced92
commit
ef87c0edae
@ -19,6 +19,9 @@ import (
|
||||
// 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) {
|
||||
if err := checkPub(pub); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k := (pub.N.BitLen() + 7) / 8
|
||||
if len(msg) > k-11 {
|
||||
err = ErrMessageTooLong
|
||||
@ -47,6 +50,9 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
|
||||
// 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) {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
|
||||
if err == nil && valid == 0 {
|
||||
err = ErrDecryption
|
||||
@ -69,6 +75,9 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [
|
||||
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
|
||||
// (Crypto '98).
|
||||
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return err
|
||||
}
|
||||
k := (priv.N.BitLen() + 7) / 8
|
||||
if k-(len(key)+3+8) < 0 {
|
||||
err = ErrDecryption
|
||||
|
@ -25,6 +25,30 @@ type PublicKey struct {
|
||||
E int // public exponent
|
||||
}
|
||||
|
||||
var (
|
||||
errPublicModulus = errors.New("crypto/rsa: missing public modulus")
|
||||
errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
|
||||
errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
|
||||
)
|
||||
|
||||
// checkPub sanity checks the public key before we use it.
|
||||
// We require pub.E to fit into a 32-bit integer so that we
|
||||
// do not have different behavior depending on whether
|
||||
// int is 32 or 64 bits. See also
|
||||
// http://www.imperialviolet.org/2012/03/16/rsae.html.
|
||||
func checkPub(pub *PublicKey) error {
|
||||
if pub.N == nil {
|
||||
return errPublicModulus
|
||||
}
|
||||
if pub.E < 2 {
|
||||
return errPublicExponentSmall
|
||||
}
|
||||
if pub.E > 1<<31-1 {
|
||||
return errPublicExponentLarge
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A PrivateKey represents an RSA key
|
||||
type PrivateKey struct {
|
||||
PublicKey // public part.
|
||||
@ -57,6 +81,10 @@ type CRTValue struct {
|
||||
// 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 {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -216,6 +244,9 @@ func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
|
||||
// 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) {
|
||||
if err := checkPub(pub); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash.Reset()
|
||||
k := (pub.N.BitLen() + 7) / 8
|
||||
if len(msg) > k-2*hash.Size()-2 {
|
||||
@ -402,6 +433,9 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er
|
||||
// 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) {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k := (priv.N.BitLen() + 7) / 8
|
||||
if len(ciphertext) > k ||
|
||||
k < hash.Size()*2+2 {
|
||||
|
Loading…
Reference in New Issue
Block a user