mirror of
https://github.com/golang/go
synced 2024-11-22 01:14:40 -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
|
// WARNING: use of this function to encrypt plaintexts other than session keys
|
||||||
// is dangerous. Use RSA OAEP in new protocols.
|
// is dangerous. Use RSA OAEP in new protocols.
|
||||||
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) {
|
||||||
|
if err := checkPub(pub); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
k := (pub.N.BitLen() + 7) / 8
|
k := (pub.N.BitLen() + 7) / 8
|
||||||
if len(msg) > k-11 {
|
if len(msg) > k-11 {
|
||||||
err = ErrMessageTooLong
|
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.
|
// 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.
|
// 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) {
|
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)
|
valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
|
||||||
if err == nil && valid == 0 {
|
if err == nil && valid == 0 {
|
||||||
err = ErrDecryption
|
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
|
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
|
||||||
// (Crypto '98).
|
// (Crypto '98).
|
||||||
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) {
|
||||||
|
if err := checkPub(&priv.PublicKey); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
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 = ErrDecryption
|
err = ErrDecryption
|
||||||
|
@ -25,6 +25,30 @@ type PublicKey struct {
|
|||||||
E int // public exponent
|
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
|
// A PrivateKey represents an RSA key
|
||||||
type PrivateKey struct {
|
type PrivateKey struct {
|
||||||
PublicKey // public part.
|
PublicKey // public part.
|
||||||
@ -57,6 +81,10 @@ type CRTValue struct {
|
|||||||
// Validate performs basic sanity checks on the key.
|
// Validate performs basic sanity checks on the key.
|
||||||
// It returns nil if the key is valid, or else an error describing a problem.
|
// It returns nil if the key is valid, or else an error describing a problem.
|
||||||
func (priv *PrivateKey) Validate() error {
|
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
|
// Check that the prime factors are actually prime. Note that this is
|
||||||
// just a sanity check. Since the random witnesses chosen by
|
// just a sanity check. Since the random witnesses chosen by
|
||||||
// ProbablyPrime are deterministic, given the candidate number, it's
|
// 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
|
// The message must be no longer than the length of the public modulus less
|
||||||
// twice the hash length plus 2.
|
// twice the hash length plus 2.
|
||||||
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
|
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()
|
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 {
|
||||||
@ -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.
|
// DecryptOAEP decrypts ciphertext using RSA-OAEP.
|
||||||
// If random != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks.
|
// 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) {
|
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
|
k := (priv.N.BitLen() + 7) / 8
|
||||||
if len(ciphertext) > k ||
|
if len(ciphertext) > k ||
|
||||||
k < hash.Size()*2+2 {
|
k < hash.Size()*2+2 {
|
||||||
|
Loading…
Reference in New Issue
Block a user