Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/rsa: x509.MarshalPKCS1PrivateKey PKCS#1 form is missing fields #987

Closed
gopherbot opened this issue Aug 1, 2010 · 3 comments
Closed

Comments

@gopherbot
Copy link

by jdnurmi:

x509.MarshalPKCS1PrivateKey purports to create a PKCS1 private key, however it actually
falls a little short of spec, and thus can't be (directly) utilized by other SSL
toolkits.

http://tools.ietf.org/html/rfc3447#appendix-A.1.2

It would appear the marshalled form is missing the derivable exponent1, exponent2, and
coefficient, and some unknown (to me) quantity called "otherPrimeInfos" that I
actually have no clue about, but seems to be required for version 1 rsa pkcs.

Once it's correct, one would expect to be able to parse with 'openssl rsa -inform DER'
@gopherbot
Copy link
Author

Comment 1 by jdnurmi:

Ok, I really wanted this, so I started hacking around to prove I wasn't crazy.
The following will generate a pkcs1 key (only version 0, since I still don't understand
oPI, but that seems to be sufficient to make openssl happy.
*** There's also a flaw in the current implementation I saw -- integers must be encoded
to follow DER, (see http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
; Section 8.3;);  
This is related to, but not directly fixed by issue/997, as it relates to the encoding
of 'big' to ASN1 (which is done in the PKCS1 Marshalling function of the x509 module).
Since 2s complement encoding is used, so if you have a very large number whose first bit
in the Byte-series is 1, the encoding would be interpreted to be negative by other ASN.1
interpreters.  RSA does not generally use negative numbers.
IMHO, A better solution would be to either always pad the result of big.Byte() if
necessary to represent the sign correctly, or add an big.SignedBytes() internally that
could evaluate the pos/neg of the big;  The below is just a hack to do the encoding
"correctly", so I can generate a PEM.
type otherPrimeInfos struct {
  Prime asn1.RawValue
  Exponent asn1.RawValue
  Coefficient asn1.RawValue
}
type pkcs1Key struct {
  Version int
  N       asn1.RawValue
  E       int
  D       asn1.RawValue
  P       asn1.RawValue
  Q       asn1.RawValue
  Exponent1 asn1.RawValue
  Exponent2 asn1.RawValue
  Coefficient asn1.RawValue
  //OtherPrimeInfos []otherPrimeInfos
}
func BigInt2ASN(t int, b *big.Int)(asn1.RawValue){
  origBytes := b.Bytes()
  if origBytes[0] & 0x80 == 0x80 {
    newBytes := make([]byte, len(origBytes) + 1)
    copy(newBytes[1:], origBytes)
    return asn1.RawValue{Tag: t, Bytes: newBytes}
  }
  return asn1.RawValue{Tag: t, Bytes: origBytes}
}
func setuppkcs1Key(pk *rsa.PrivateKey) (b []byte, err os.Error ){
  k := pkcs1Key {
    Version: 0,
    N: BigInt2ASN(2, pk.N),
    E: pk.PublicKey.E,
    D: BigInt2ASN(2, pk.D),
    P: BigInt2ASN(2, pk.P),
    Q: BigInt2ASN(2, pk.Q),
  }
  //k.OtherPrimeInfos = make([]otherPrimeInfos, 0)
  minusone := big.NewInt(-1)
  one := big.NewInt(1)
  q_1 := big.NewInt(0).Sub(pk.Q, one)
  p_1 := big.NewInt(0).Sub(pk.P, one)
  exp1 := big.NewInt(0).Mod(pk.D, p_1)
  exp2 := big.NewInt(0).Mod(pk.D, q_1)
  coeff := big.NewInt(0).Exp(pk.Q, minusone, pk.P)
  k.Exponent1 = BigInt2ASN(2, exp1)
  k.Exponent2 = BigInt2ASN(2, exp2)
  k.Coefficient = BigInt2ASN(2, coeff)
  b, err = asn1.MarshalToMemory(k)
  return
}

@rsc
Copy link
Contributor

rsc commented Oct 11, 2010

Comment 2:

-> agl for triage

Owner changed to a...@golang.org.

Status changed to Accepted.

@agl
Copy link
Contributor

agl commented Apr 22, 2011

Comment 3:

This issue was closed by revision 555685e.

Status changed to Fixed.

@mikioh mikioh changed the title x509.MarshalPKCS1PrivateKey PKCS#1 form is missing fields crypto/rsa: x509.MarshalPKCS1PrivateKey PKCS#1 form is missing fields Jan 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
FiloSottile pushed a commit to FiloSottile/go that referenced this issue Oct 12, 2018
With full multi-prime support we can support version 1 PKCS#1 private
keys. This means exporting all the members of rsa.PrivateKey, thus
making the API a little messy. However there has already been another
request to export this so it seems to be something that's needed.

Over time, rsa.GenerateMultiPrimeKey will replace rsa.GenerateKey, but
I need to work on the prime balance first because we're no longer
generating primes which are a multiples of 8 bits.

Fixes golang#987.

R=rsc
CC=golang-dev
https://golang.org/cl/4378046
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants