summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/crypto/rsa')
-rw-r--r--src/pkg/crypto/rsa/pkcs1v15.go12
-rw-r--r--src/pkg/crypto/rsa/pkcs1v15_test.go22
-rw-r--r--src/pkg/crypto/rsa/pss.go6
-rw-r--r--src/pkg/crypto/rsa/rsa.go14
-rw-r--r--src/pkg/crypto/rsa/rsa_test.go2
5 files changed, 44 insertions, 12 deletions
diff --git a/src/pkg/crypto/rsa/pkcs1v15.go b/src/pkg/crypto/rsa/pkcs1v15.go
index 1a055a3d6..d9957aec1 100644
--- a/src/pkg/crypto/rsa/pkcs1v15.go
+++ b/src/pkg/crypto/rsa/pkcs1v15.go
@@ -176,7 +176,8 @@ var hashPrefixes = map[crypto.Hash][]byte{
// 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.
+// given hash function. If hash is zero, hashed is signed directly. This isn't
+// advisable except for interoperability.
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 {
@@ -212,7 +213,8 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
// 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.
+// returning a nil error. If hash is zero then hashed is used directly. This
+// isn't advisable except for interoperability.
func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (err error) {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
@@ -249,6 +251,12 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte)
}
func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
+ // Special case: crypto.Hash(0) is used to indicate that the data is
+ // signed directly.
+ if hash == 0 {
+ return inLen, nil, nil
+ }
+
hashLen = hash.Size()
if inLen != hashLen {
return 0, nil, errors.New("crypto/rsa: input must be hashed message")
diff --git a/src/pkg/crypto/rsa/pkcs1v15_test.go b/src/pkg/crypto/rsa/pkcs1v15_test.go
index 70bb22889..37c14d1d9 100644
--- a/src/pkg/crypto/rsa/pkcs1v15_test.go
+++ b/src/pkg/crypto/rsa/pkcs1v15_test.go
@@ -205,6 +205,28 @@ func TestOverlongMessagePKCS1v15(t *testing.T) {
}
}
+func TestUnpaddedSignature(t *testing.T) {
+ msg := []byte("Thu Dec 19 18:06:16 EST 2013\n")
+ // This base64 value was generated with:
+ // % echo Thu Dec 19 18:06:16 EST 2013 > /tmp/msg
+ // % openssl rsautl -sign -inkey key -out /tmp/sig -in /tmp/msg
+ //
+ // Where "key" contains the RSA private key given at the bottom of this
+ // file.
+ expectedSig := decodeBase64("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==")
+
+ sig, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.Hash(0), msg)
+ if err != nil {
+ t.Fatalf("SignPKCS1v15 failed: %s", err)
+ }
+ if !bytes.Equal(sig, expectedSig) {
+ t.Fatalf("signature is not expected value: got %x, want %x", sig, expectedSig)
+ }
+ if err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.Hash(0), msg, sig); err != nil {
+ t.Fatalf("signature failed to verify: %s", err)
+ }
+}
+
// In order to generate new test vectors you'll need the PEM form of this key:
// -----BEGIN RSA PRIVATE KEY-----
// MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
diff --git a/src/pkg/crypto/rsa/pss.go b/src/pkg/crypto/rsa/pss.go
index f9abec394..18eafbc05 100644
--- a/src/pkg/crypto/rsa/pss.go
+++ b/src/pkg/crypto/rsa/pss.go
@@ -4,7 +4,7 @@
package rsa
-// This file implementes the PSS signature scheme [1].
+// This file implements the PSS signature scheme [1].
//
// [1] http://www.rsa.com/rsalabs/pkcs/files/h11300-wp-pkcs-1v2-2-rsa-cryptography-standard.pdf
@@ -189,7 +189,7 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
// signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt.
// Note that hashed must be the result of hashing the input message using the
-// given hash funcion. salt is a random sequence of bytes whose length will be
+// given hash function. salt is a random sequence of bytes whose length will be
// later used to verify the signature.
func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) {
nBits := priv.N.BitLen()
@@ -233,7 +233,7 @@ func (opts *PSSOptions) saltLength() int {
// SignPSS calculates the signature of hashed using RSASSA-PSS [1].
// Note that hashed must be the result of hashing the input message using the
-// given hash funcion. The opts argument may be nil, in which case sensible
+// given hash function. The opts argument may be nil, in which case sensible
// defaults are used.
func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) (s []byte, err error) {
saltLength := opts.saltLength()
diff --git a/src/pkg/crypto/rsa/rsa.go b/src/pkg/crypto/rsa/rsa.go
index c7353ea31..bce6ba4eb 100644
--- a/src/pkg/crypto/rsa/rsa.go
+++ b/src/pkg/crypto/rsa/rsa.go
@@ -60,7 +60,7 @@ type PrivateKey struct {
type PrecomputedValues struct {
Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
- Qinv *big.Int // Q^-1 mod Q
+ Qinv *big.Int // Q^-1 mod P
// CRTValues is used for the 3rd and subsequent primes. Due to a
// historical accident, the CRT for the first two primes is handled
@@ -120,16 +120,18 @@ func (priv *PrivateKey) Validate() error {
return nil
}
-// GenerateKey generates an RSA keypair of the given bit size.
+// GenerateKey generates an RSA keypair of the given bit size using the
+// random source random (for example, crypto/rand.Reader).
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.
+// size and the given random source, 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.
//
diff --git a/src/pkg/crypto/rsa/rsa_test.go b/src/pkg/crypto/rsa/rsa_test.go
index cf193c669..4ee1c3a8b 100644
--- a/src/pkg/crypto/rsa/rsa_test.go
+++ b/src/pkg/crypto/rsa/rsa_test.go
@@ -197,7 +197,7 @@ func TestEncryptOAEP(t *testing.T) {
public := PublicKey{n, test.e}
for j, message := range test.msgs {
- randomSource := bytes.NewBuffer(message.seed)
+ randomSource := bytes.NewReader(message.seed)
out, err := EncryptOAEP(sha1, randomSource, &public, message.in, nil)
if err != nil {
t.Errorf("#%d,%d error: %s", i, j, err)