Add PKCS#1 RSA key related helpers stolen from orkey.

These routines can handle Tor's idea of an RSA key, assuming PEM/Base64
handling is done as appropriate.
This commit is contained in:
Yawning Angel 2015-10-08 23:19:35 +00:00
parent 28616763d2
commit f6128d70b6
1 changed files with 85 additions and 0 deletions

85
utils/pkcs1/rsa.go Normal file
View File

@ -0,0 +1,85 @@
//
// rsa.go - PKCS#1 RSA key related helpers.
//
// To the extent possible under law, Yawning Angel has waived all copyright and
// related or neighboring rights to bulb, using the creative commons
// "cc0" public domain dedication. See LICENSE or
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
// Package pkcs1 implements PKCS#1 RSA key marshalling/unmarshalling,
// compatibile with Tor's usage.
package pkcs1
import (
"crypto/rsa"
"encoding/asn1"
"math/big"
)
type pkcs1RSAPrivKey struct {
Version int // version
N *big.Int // modulus
E int // publicExponent
D *big.Int // privateExponent
P *big.Int // prime1
Q *big.Int // prime2
Dp *big.Int // exponent1: d mod (p-1)
Dq *big.Int // exponent2: d mod (q-1)
Qinv *big.Int // coefficient: (inverse of q) mod p
}
// EncodePrivateKeyDER returns the PKCS#1 DER encoding of a rsa.PrivateKey.
func EncodePrivateKeyDER(sk *rsa.PrivateKey) ([]byte, error) {
// The crypto.RSA structure has a slightly different layout than PKCS#1
// private keys, so directly marshaling does not work. Pull out the values
// into a strucuture with the correct layout and marshal.
sk.Precompute() // Ensure that the structure is fully populated.
k := pkcs1RSAPrivKey{
Version: 0,
N: sk.N,
E: sk.E,
D: sk.D,
P: sk.Primes[0],
Q: sk.Primes[1],
Dp: sk.Precomputed.Dp,
Dq: sk.Precomputed.Dq,
Qinv: sk.Precomputed.Qinv,
}
return asn1.Marshal(k)
}
// DecodePrivateKeyDER returns the rsa.PrivateKey decoding of a PKCS#1 DER blob.
func DecodePrivateKeyDER(b []byte) (*rsa.PrivateKey, []byte, error) {
var k pkcs1RSAPrivKey
rest, err := asn1.Unmarshal(b, &k)
if err == nil {
sk := &rsa.PrivateKey{}
sk.Primes = make([]*big.Int, 2)
sk.N = k.N
sk.E = k.E
sk.D = k.D
sk.Primes[0] = k.P
sk.Primes[1] = k.Q
// Ignore the precomputed values and just rederive them.
sk.Precompute()
return sk, rest, nil
}
return nil, rest, err
}
// EncodePublicKeyDER returns the PKCS#1 DER encoding of a rsa.PublicKey.
func EncodePublicKeyDER(pk *rsa.PublicKey) ([]byte, error) {
// The crypto.RSA structure is exactly the same as the PCKS#1 public keys,
// when the encoding/asn.1 marshaller is done with it.
//
// DER encoding of (SEQUENCE | INTEGER(n) | INTEGER(e))
return asn1.Marshal(*pk)
}
// DecodePublicKeyDER returns the rsa.PublicKey decoding of a PKCS#1 DER blob.
func DecodePublicKeyDER(b []byte) (*rsa.PublicKey, []byte, error) {
pk := &rsa.PublicKey{}
rest, err := asn1.Unmarshal(b, pk)
return pk, rest, err
}