On 1/24/2022 9:51 AM, Sean Mullan wrote:
On Sat, 22 Jan 2022 22:48:29 GMT, Michael StJohns <mstjo...@comcast.net> wrote:

I originally started using the BC certificate factory
because the SUN factory didn't understand RSA-OAEP as a key type in
SubjectKeyInfo and I was getting a few of those from a group of TPMs.??
Is that still an issue? I would have expected this to be fixed since JDK 11 
when we added support for RSASSA-PSS.
*sigh* doing archeology on my code, that may not have been the reason I started using the BC factory.  I *think* I ran into another rogue certificate that the SUN library couldn't parse, but the BC library code.  However, the RSA-OAEP thing does exist.  See below

-------------

PR: https://git.openjdk.java.net/jdk/pull/6928

Looks like it probably wasn't fixed.    This was actually an OID in the SubjectKeyInfo meant to indicate that the RSA key was solely to be used for OAEP.  I.e. 1.2.840.113549.1.1.7.  The place this gets rejected is in (looking at the current github) - sun/crypto/provider/RSACipher.java @line 261: RSAKey rsaKey = RSAKeyFactory.toRSAKey(key);

That calls sun/security/rsa/RSAKeyFactory.java::toRSAKey(Key key), which in turn calls sun/security/rsa/RSAUtil.KeyType::lookup(key.getAlgorithm()) @line 128.  That fails because the key is neither the rsaEncryption OID (1.2.840.113549.1.1.1) nor RSASSA_PSS_oid (.... .10).


Here's the function I use to fix the encoding. Basically, it changes the last octet of the key's algorithmID from a '7' to a '1' and regenerates the key.

  public static PublicKey fixPubKey (PublicKey k)
    throws PrivacyCAException{
    if (!k.getAlgorithm().equals("1.2.840.113549.1.1.7"))
      return k;  // its not a problem
    byte[] encodedKey = k.getEncoded();
    encodedKey[16] = (byte)1;
    X509EncodedKeySpec kspec = new X509EncodedKeySpec(encodedKey);

    try {
      KeyFactory kf = KeyFactory.getInstance("RSA");
      return kf.generatePublic(kspec);
    } catch (GeneralSecurityException ex) {
      throw new PrivacyCAException ("Unable to convert an OAEP RSA Public Key to a normal RSA public key", ex);
    }
  }

The fixed public key is fed to this code code which worked even in JDK8:

Cipher rsaoaep = Cipher.getInstance ("RSA/ECB/oaepwithsha1andmgf1padding", "SunJCE");
    String hashName = "SHA-256"; // name alg hash for EK?
    String hmacName = "HmacSHA256";
    int hashLen = 256;
    byte[] identityLabel = Charset.forName("UTF-8").encode("IDENTITY").array();

    // zero terminate
    identityLabel = Arrays.copyOf(identityLabel, identityLabel.length + 1);
    logBuffer("Identity label", identityLabel);
    OAEPParameterSpec oaepspec =
      new OAEPParameterSpec (hashName, "MGF1", new MGF1ParameterSpec (hashName),
                 new PSource.PSpecified(identityLabel));
    rsaoaep.init (Cipher.ENCRYPT_MODE, ekPubKey, oaepspec);
    byte[] encryptedSeed = rsaoaep.doFinal(seed);

If I get a chance, I'll try and take a properly formatted RSA (.1) key and turn it into an RSAOAEP  (.7) key and see what happens with the above code.  It may take a few days.

AFAIK, this convention was only used by the TPM1.2 space, and only briefly as it was realized it was a backwards compatibility nightmare.  It was actually in an early version of the TPM spec and then removed.  I haven't seen any of these keys in any of the TPM2.0s I've played with.

Strangely, I haven't seen any PSS (.10) (vs OAEP) encoded keys.

Mike



Reply via email to