<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">On 9/4/2018 3:19 PM, Adam Petcher
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:77ab28a5-8b14-db97-941e-7d3783a4f4c9@oracle.com">I think
      what you are suggesting is that the implementation should convert
      between BigInteger and the internal representation when necessary.
      The problem with this approach is that it is too easy to
      inadvertently supply a BigInteger to the implementation, and this
      would result in a branch. I understand that this branch may be
      acceptable in some circumstances, but we would need something in
      the API to tell the implementation whether it is okay to branch or
      not. I think the simplest way to do that is to have a provider
      that never branches. If branching is okay, then SunEC can be used.
      <br>
    </blockquote>
    <p>Basically yes.   <br>
    </p>
    <p>But I don't understand what you mean by "inadvertently supply a
      BigInteger"?  AFAICT, you "supply" a BigInteger in an
      ECPrivateKeySpec and you retrieve one when you call getEncoded()
      or getS().    Your implementation would convert between the
      BigInteger and internal representation during the use of the
      engineGeneratePrivate() method of the KeyFactorySpi and would
      convert from your internal representation when exporting S, or
      encoding something as PKCS8.</p>
    <p>Again - you're wrongly conflating interface requirements with
      implementation requirements.  <br>
    </p>
    <p>And how do you expect to move key material between SunEC and this
      implementation?  See below for my commentary on that.<br>
    </p>
    <p><br>
    </p>
    <p>
      <blockquote type="cite">That's essentially the plan. Calling
        PrivateKey::getEncoded will return null, which is a convention
        for non-extractable keys. Trying to convert from/to an
        ECPrivateKeySpec using the KeyFactory in the new provider will
        result in an exception---so you won't have an object to call
        getS() on.
        <br>
      </blockquote>
      That's not what PKCS11 does - it just gives you a "PrivateKey"
      object with an internal type of sun.security.pkcs11.P11Key.  While
      that object is not type safe exactly, it is provider safe.<br>
    </p>
    <p>You're still wanting to use the various EC classes of
      java.security, java.security.spec, and java.security.interfaces,
      but you're unwilling to actually meet their contracts for some
      really suspect reasons.<br>
    </p>
    <p><br>
      <blockquote type="cite">
        <br>
        To create the key from stored information, the best way is to
        construct a PKCS8EncodedKeySpec using the encoded key. If you
        are starting with a BigInteger, and if branching is acceptable,
        you can use the KeyFactory from SunEC to convert an
        ECPrivateKeySpec to PrivateKey to get the encoded value.
      </blockquote>
    </p>
    <p>Umm... what?  <br>
    </p>
    <p>If you were doing NewEC -> SunEC manually (getEncoded() ->
      KeySpec) - you'll need to end up emitting a PKCS8 blob using
      RFC5915, which - unsurprisingly has  BigEndian INTEGERs  (yes, its
      an octet string, but the encoding is specified by RFC3447 as
      pretty much the big endian encoding of an integer).  E.g. it may
      look opaque from Java's point of view, but it's not really opaque.
      (See below)<br>
    </p>
    <p>Or have you got a different way of encoding the PKCS8 blob for
      the new provider?  E.g. point me at a specification please.</p>
    <p>My head hurt when I tried to work through the various cases of
      translating a private key from your provider to SunEC or to
      BouncyCastle and vice versa.  Basically, if you don't support the
      getS() call, then KeyFactory.translateKey() will fail.  (Below
      from sun.security.ec.ECKeyFactory.java - the SunEC provider's
      implementation).<br>
    </p>
    <p>
      <blockquote type="cite"> private PrivateKey
        implTranslatePrivateKey(PrivateKey key)<br>
                    throws InvalidKeyException {<br>
                if (key instanceof ECPrivateKey) {<br>
                    if (key instanceof ECPrivateKeyImpl) {<br>
                        return key;<br>
                    }<br>
                    ECPrivateKey ecKey = (ECPrivateKey)key;<br>
                    return new ECPrivateKeyImpl(<br>
                        ecKey.getS(),<br>
                        ecKey.getParams()<br>
                    );<br>
                } else if ("PKCS#8".equals(key.getFormat())) {<br>
                    return new ECPrivateKeyImpl(key.getEncoded());<br>
                } else {<br>
                    throw new InvalidKeyException("Private keys must be
        instance "<br>
                        + "of ECPrivateKey or have PKCS#8 encoding");<br>
                }<br>
            </blockquote>
      <br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <p>
      <blockquote type="cite">
        <pre class="newpage"><span class="h3"><h3><a class="selflink" name="section-4.1" href="https://tools.ietf.org/html/rfc3447#section-4.1">4.1</a> I2OSP</h3></span>

   I2OSP converts a nonnegative integer to an octet string of a
   specified length.

   I2OSP (x, xLen)

   Input:
   x        nonnegative integer to be converted
   xLen     intended length of the resulting octet string

   Output:
   X        corresponding octet string of length xLen

   Error: "integer too large"

   Steps:

   1. If x >= 256^xLen, output "integer too large" and stop.

   2. Write the integer x in its unique xLen-digit representation in
      base 256:

         x = x_(xLen-1) 256^(xLen-1) + x_(xLen-2) 256^(xLen-2) + ...
         + x_1 256 + x_0,

      where 0 <= x_i < 256 (note that one or more leading digits will be
      zero if x is less than 256^(xLen-1)).

   3. Let the octet X_i have the integer value x_(xLen-i) for 1 <= i <=
      xLen.  Output the octet string

         X = X_1 X_2 ... X_xLen.
</pre>
      </blockquote>
      <br>
    </p>
  </body>
</html>