--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import sun.security.util.Length;
+
+import java.security.Key;
+
+/**
+ * The handle for a key using the Microsoft Crypto API.
+ *
+ * @see CPrivateKey
+ * @see CPublicKey
+ *
+ * @since 1.6
+ * @author Stanley Man-Kit Ho
+ */
+abstract class CKey implements Key, Length {
+ private static final long serialVersionUID = -1088859394025049194L;
+
+ static class NativeHandles {
+
+ long hCryptProv = 0;
+ long hCryptKey = 0;
+
+ public NativeHandles(long hCryptProv, long hCryptKey) {
+ this.hCryptProv = hCryptProv;
+ this.hCryptKey = hCryptKey;
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void finalize() throws Throwable {
+ try {
+ synchronized(this) {
+ cleanUp(hCryptProv, hCryptKey);
+ hCryptProv = 0;
+ hCryptKey = 0;
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+ }
+
+ protected final NativeHandles handles;
+
+ protected final int keyLength;
+
+ protected final String algorithm;
+
+ protected CKey(String algorithm, long hCryptProv, long hCryptKey, int keyLength) {
+ this.algorithm = algorithm;
+ this.handles = new NativeHandles(hCryptProv, hCryptKey);
+ this.keyLength = keyLength;
+ }
+
+ // Native method to cleanup the key handle.
+ private native static void cleanUp(long hCryptProv, long hCryptKey);
+
+ @Override
+ public int length() {
+ return keyLength;
+ }
+
+ public long getHCryptKey() {
+ return handles.hCryptKey;
+ }
+
+ public long getHCryptProvider() {
+ return handles.hCryptProv;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ protected native static String getContainerName(long hCryptProv);
+
+ protected native static String getKeyType(long hCryptKey);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyPair.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+/**
+ * The handle for an RSA public/private keypair using the Microsoft Crypto API.
+ *
+ * @since 1.6
+ */
+class CKeyPair {
+
+ private final CPrivateKey privateKey;
+
+ private final CPublicKey publicKey;
+
+ CKeyPair(String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ privateKey = CPrivateKey.of(alg, hCryptProv, hCryptKey, keyLength);
+ publicKey = CPublicKey.of(alg, hCryptProv, hCryptKey, keyLength);
+ }
+
+ public CPrivateKey getPrivate() {
+ return privateKey;
+ }
+
+ public CPublicKey getPublic() {
+ return publicKey;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyPairGenerator.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.util.UUID;
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import sun.security.rsa.RSAKeyFactory;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+
+/**
+ * RSA keypair generator.
+ *
+ * Standard algorithm, minimum key length is 512 bit, maximum is 16,384.
+ * Generates a private key that is exportable.
+ *
+ * @since 1.6
+ */
+public abstract class CKeyPairGenerator extends KeyPairGeneratorSpi {
+
+ protected String keyAlg;
+
+ public CKeyPairGenerator(String keyAlg) {
+ this.keyAlg = keyAlg;
+ }
+
+ public static class RSA extends CKeyPairGenerator {
+ public RSA() {
+ super("RSA");
+ // initialize to default in case the app does not call initialize()
+ initialize(DEF_RSA_KEY_SIZE, null);
+ }
+
+ // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
+ static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
+ static final int KEY_SIZE_MAX = 16384;
+
+ // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
+ private int keySize;
+
+ // initialize the generator. See JCA doc
+ // random is always ignored
+ @Override
+ public void initialize(int keySize, SecureRandom random) {
+
+ try {
+ RSAKeyFactory.checkKeyLengths(keySize, null,
+ KEY_SIZE_MIN, KEY_SIZE_MAX);
+ } catch (InvalidKeyException e) {
+ throw new InvalidParameterException(e.getMessage());
+ }
+
+ this.keySize = keySize;
+ }
+
+ // second initialize method. See JCA doc
+ // random and exponent are always ignored
+ @Override
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+
+ int tmpSize;
+ if (params == null) {
+ tmpSize = DEF_RSA_KEY_SIZE;
+ } else if (params instanceof RSAKeyGenParameterSpec) {
+
+ if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
+ throw new InvalidAlgorithmParameterException
+ ("Exponent parameter is not supported");
+ }
+ tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
+
+ } else {
+ throw new InvalidAlgorithmParameterException
+ ("Params must be an instance of RSAKeyGenParameterSpec");
+ }
+
+ try {
+ RSAKeyFactory.checkKeyLengths(tmpSize, null,
+ KEY_SIZE_MIN, KEY_SIZE_MAX);
+ } catch (InvalidKeyException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid Key sizes", e);
+ }
+
+ this.keySize = tmpSize;
+ }
+
+ // generate the keypair. See JCA doc
+ @Override
+ public KeyPair generateKeyPair() {
+
+ try {
+ // Generate each keypair in a unique key container
+ CKeyPair keys =
+ generateCKeyPair(keyAlg, keySize,
+ "{" + UUID.randomUUID().toString() + "}");
+ return new KeyPair(keys.getPublic(), keys.getPrivate());
+
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+
+ private static native CKeyPair generateCKeyPair(String alg, int keySize,
+ String keyContainerName) throws KeyException;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,880 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyStoreSpi;
+import java.security.KeyStoreException;
+import java.security.PrivilegedAction;
+import java.security.UnrecoverableKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecurityPermission;
+import java.security.cert.X509Certificate;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.util.*;
+
+/**
+ * Implementation of key store for Windows using the Microsoft Crypto API.
+ *
+ * @since 1.6
+ */
+abstract class CKeyStore extends KeyStoreSpi {
+
+ public static final class MY extends CKeyStore {
+ public MY() {
+ super("MY");
+ }
+ }
+
+ public static final class ROOT extends CKeyStore {
+ public ROOT() {
+ super("ROOT");
+ }
+ }
+
+ class KeyEntry {
+ private CKey privateKey;
+ private X509Certificate[] certChain;
+ private String alias;
+
+ KeyEntry(CKey key, X509Certificate[] chain) {
+ this(null, key, chain);
+ }
+
+ KeyEntry(String alias, CKey key, X509Certificate[] chain) {
+ this.privateKey = key;
+ this.certChain = chain;
+ /*
+ * The default alias for both entry types is derived from a
+ * hash value intrinsic to the first certificate in the chain.
+ */
+ if (alias == null) {
+ this.alias = Integer.toString(chain[0].hashCode());
+ } else {
+ this.alias = alias;
+ }
+ }
+
+ /**
+ * Gets the alias for the keystore entry.
+ */
+ String getAlias() {
+ return alias;
+ }
+
+ /**
+ * Sets the alias for the keystore entry.
+ */
+ void setAlias(String alias) {
+ // TODO - set friendly name prop in cert store
+ this.alias = alias;
+ }
+
+ /**
+ * Gets the private key for the keystore entry.
+ */
+ CKey getPrivateKey() {
+ return privateKey;
+ }
+
+ /**
+ * Sets the private key for the keystore entry.
+ */
+ void setRSAPrivateKey(Key k)
+ throws InvalidKeyException, KeyStoreException {
+ RSAPrivateCrtKey key = (RSAPrivateCrtKey) k;
+ byte[] modulusBytes = key.getModulus().toByteArray();
+
+ // Adjust key length due to sign bit
+ int keyBitLength = (modulusBytes[0] == 0)
+ ? (modulusBytes.length - 1) * 8
+ : modulusBytes.length * 8;
+
+ byte[] keyBlob = generateRSAPrivateKeyBlob(
+ keyBitLength,
+ modulusBytes,
+ key.getPublicExponent().toByteArray(),
+ key.getPrivateExponent().toByteArray(),
+ key.getPrimeP().toByteArray(),
+ key.getPrimeQ().toByteArray(),
+ key.getPrimeExponentP().toByteArray(),
+ key.getPrimeExponentQ().toByteArray(),
+ key.getCrtCoefficient().toByteArray());
+
+ privateKey = storePrivateKey("RSA", Objects.requireNonNull(keyBlob),
+ "{" + UUID.randomUUID().toString() + "}", keyBitLength);
+ }
+
+ /**
+ * Gets the certificate chain for the keystore entry.
+ */
+ X509Certificate[] getCertificateChain() {
+ return certChain;
+ }
+
+ /**
+ * Sets the certificate chain for the keystore entry.
+ */
+ void setCertificateChain(X509Certificate[] chain)
+ throws CertificateException, KeyStoreException {
+ for (int i = 0; i < chain.length; i++) {
+ byte[] encoding = chain[i].getEncoded();
+ if (i == 0 && privateKey != null) {
+ storeCertificate(getName(), alias, encoding,
+ encoding.length, privateKey.getHCryptProvider(),
+ privateKey.getHCryptKey());
+
+ } else {
+ storeCertificate(getName(), alias, encoding,
+ encoding.length, 0L, 0L); // no private key to attach
+ }
+ }
+ certChain = chain;
+ }
+ }
+
+ /*
+ * An X.509 certificate factory.
+ * Used to create an X.509 certificate from its DER-encoding.
+ */
+ private CertificateFactory certificateFactory = null;
+
+ /*
+ * Compatibility mode: for applications that assume keystores are
+ * stream-based this mode tolerates (but ignores) a non-null stream
+ * or password parameter when passed to the load or store methods.
+ * The mode is enabled by default.
+ */
+ private static final String KEYSTORE_COMPATIBILITY_MODE_PROP =
+ "sun.security.mscapi.keyStoreCompatibilityMode";
+ private final boolean keyStoreCompatibilityMode;
+
+ /*
+ * The keystore entries.
+ * Keys in the map are unique aliases (thus can differ from
+ * KeyEntry.getAlias())
+ */
+ private Map<String,KeyEntry> entries = new HashMap<>();
+
+ /*
+ * The keystore name.
+ * Case is not significant.
+ */
+ private final String storeName;
+
+ CKeyStore(String storeName) {
+ // Get the compatibility mode
+ String prop = AccessController.doPrivileged(
+ (PrivilegedAction<String>) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP));
+
+ if ("false".equalsIgnoreCase(prop)) {
+ keyStoreCompatibilityMode = false;
+ } else {
+ keyStoreCompatibilityMode = true;
+ }
+
+ this.storeName = storeName;
+ }
+
+ /**
+ * Returns the key associated with the given alias.
+ * <p>
+ * A compatibility mode is supported for applications that assume
+ * a password must be supplied. It permits (but ignores) a non-null
+ * <code>password</code>. The mode is enabled by default.
+ * Set the
+ * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
+ * system property to <code>false</code> to disable compatibility mode
+ * and reject a non-null <code>password</code>.
+ *
+ * @param alias the alias name
+ * @param password the password, which should be <code>null</code>
+ *
+ * @return the requested key, or null if the given alias does not exist
+ * or does not identify a <i>key entry</i>.
+ *
+ * @exception NoSuchAlgorithmException if the algorithm for recovering the
+ * key cannot be found,
+ * or if compatibility mode is disabled and <code>password</code> is
+ * non-null.
+ * @exception UnrecoverableKeyException if the key cannot be recovered.
+ */
+ public java.security.Key engineGetKey(String alias, char[] password)
+ throws NoSuchAlgorithmException, UnrecoverableKeyException {
+ if (alias == null) {
+ return null;
+ }
+
+ if (password != null && !keyStoreCompatibilityMode) {
+ throw new UnrecoverableKeyException("Password must be null");
+ }
+
+ if (engineIsKeyEntry(alias) == false)
+ return null;
+
+ KeyEntry entry = entries.get(alias);
+ return (entry == null)
+ ? null
+ : entry.getPrivateKey();
+ }
+
+ /**
+ * Returns the certificate chain associated with the given alias.
+ *
+ * @param alias the alias name
+ *
+ * @return the certificate chain (ordered with the user's certificate first
+ * and the root certificate authority last), or null if the given alias
+ * does not exist or does not contain a certificate chain (i.e., the given
+ * alias identifies either a <i>trusted certificate entry</i> or a
+ * <i>key entry</i> without a certificate chain).
+ */
+ public Certificate[] engineGetCertificateChain(String alias) {
+ if (alias == null) {
+ return null;
+ }
+
+ KeyEntry entry = entries.get(alias);
+ X509Certificate[] certChain = (entry == null)
+ ? null
+ : entry.getCertificateChain();
+ return (certChain == null)
+ ? null
+ : certChain.clone();
+ }
+
+ /**
+ * Returns the certificate associated with the given alias.
+ *
+ * <p>If the given alias name identifies a
+ * <i>trusted certificate entry</i>, the certificate associated with that
+ * entry is returned. If the given alias name identifies a
+ * <i>key entry</i>, the first element of the certificate chain of that
+ * entry is returned, or null if that entry does not have a certificate
+ * chain.
+ *
+ * @param alias the alias name
+ *
+ * @return the certificate, or null if the given alias does not exist or
+ * does not contain a certificate.
+ */
+ public Certificate engineGetCertificate(String alias) {
+ if (alias == null) {
+ return null;
+ }
+
+ KeyEntry entry = entries.get(alias);
+ X509Certificate[] certChain = (entry == null)
+ ? null
+ : entry.getCertificateChain();
+ return (certChain == null || certChain.length == 0)
+ ? null
+ : certChain[0];
+ }
+
+ /**
+ * Returns the creation date of the entry identified by the given alias.
+ *
+ * @param alias the alias name
+ *
+ * @return the creation date of this entry, or null if the given alias does
+ * not exist
+ */
+ public Date engineGetCreationDate(String alias) {
+ if (alias == null) {
+ return null;
+ }
+ return new Date();
+ }
+
+ /**
+ * Stores the given private key and associated certificate chain in the
+ * keystore.
+ *
+ * <p>The given java.security.PrivateKey <code>key</code> must
+ * be accompanied by a certificate chain certifying the
+ * corresponding public key.
+ *
+ * <p>If the given alias already exists, the keystore information
+ * associated with it is overridden by the given key and certificate
+ * chain. Otherwise, a new entry is created.
+ *
+ * <p>
+ * A compatibility mode is supported for applications that assume
+ * a password must be supplied. It permits (but ignores) a non-null
+ * <code>password</code>. The mode is enabled by default.
+ * Set the
+ * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
+ * system property to <code>false</code> to disable compatibility mode
+ * and reject a non-null <code>password</code>.
+ *
+ * @param alias the alias name
+ * @param key the private key to be associated with the alias
+ * @param password the password, which should be <code>null</code>
+ * @param chain the certificate chain for the corresponding public
+ * key (only required if the given key is of type
+ * <code>java.security.PrivateKey</code>).
+ *
+ * @exception KeyStoreException if the given key is not a private key,
+ * cannot be protected, or if compatibility mode is disabled and
+ * <code>password</code> is non-null, or if this operation fails for
+ * some other reason.
+ */
+ public void engineSetKeyEntry(String alias, java.security.Key key,
+ char[] password, Certificate[] chain) throws KeyStoreException {
+ if (alias == null) {
+ throw new KeyStoreException("alias must not be null");
+ }
+
+ if (password != null && !keyStoreCompatibilityMode) {
+ throw new KeyStoreException("Password must be null");
+ }
+
+ if (key instanceof RSAPrivateCrtKey) {
+
+ KeyEntry entry = entries.get(alias);
+
+ X509Certificate[] xchain;
+ if (chain != null) {
+ if (chain instanceof X509Certificate[]) {
+ xchain = (X509Certificate[]) chain;
+ } else {
+ xchain = new X509Certificate[chain.length];
+ System.arraycopy(chain, 0, xchain, 0, chain.length);
+ }
+ } else {
+ xchain = null;
+ }
+
+ if (entry == null) {
+ entry =
+ //TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
+ new KeyEntry(alias, null, xchain);
+ storeWithUniqueAlias(alias, entry);
+ }
+
+ entry.setAlias(alias);
+
+ try {
+ entry.setRSAPrivateKey(key);
+ entry.setCertificateChain(xchain);
+
+ } catch (CertificateException ce) {
+ throw new KeyStoreException(ce);
+
+ } catch (InvalidKeyException ike) {
+ throw new KeyStoreException(ike);
+ }
+
+ } else {
+ throw new UnsupportedOperationException(
+ "Cannot assign the key to the given alias.");
+ }
+ }
+
+ /**
+ * Assigns the given key (that has already been protected) to the given
+ * alias.
+ *
+ * <p>If the protected key is of type
+ * <code>java.security.PrivateKey</code>, it must be accompanied by a
+ * certificate chain certifying the corresponding public key. If the
+ * underlying keystore implementation is of type <code>jks</code>,
+ * <code>key</code> must be encoded as an
+ * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
+ *
+ * <p>If the given alias already exists, the keystore information
+ * associated with it is overridden by the given key (and possibly
+ * certificate chain).
+ *
+ * @param alias the alias name
+ * @param key the key (in protected format) to be associated with the alias
+ * @param chain the certificate chain for the corresponding public
+ * key (only useful if the protected key is of type
+ * <code>java.security.PrivateKey</code>).
+ *
+ * @exception KeyStoreException if this operation fails.
+ */
+ public void engineSetKeyEntry(String alias, byte[] key,
+ Certificate[] chain)
+ throws KeyStoreException {
+ throw new UnsupportedOperationException(
+ "Cannot assign the encoded key to the given alias.");
+ }
+
+ /**
+ * Assigns the given certificate to the given alias.
+ *
+ * <p>If the given alias already exists in this keystore and identifies a
+ * <i>trusted certificate entry</i>, the certificate associated with it is
+ * overridden by the given certificate.
+ *
+ * @param alias the alias name
+ * @param cert the certificate
+ *
+ * @exception KeyStoreException if the given alias already exists and does
+ * not identify a <i>trusted certificate entry</i>, or this operation
+ * fails for some other reason.
+ */
+ public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException {
+ if (alias == null) {
+ throw new KeyStoreException("alias must not be null");
+ }
+
+ if (cert instanceof X509Certificate) {
+
+ // TODO - build CryptoAPI chain?
+ X509Certificate[] chain =
+ new X509Certificate[]{ (X509Certificate) cert };
+ KeyEntry entry = entries.get(alias);
+
+ if (entry == null) {
+ entry =
+ new KeyEntry(alias, null, chain);
+ storeWithUniqueAlias(alias, entry);
+ }
+
+ if (entry.getPrivateKey() == null) { // trusted-cert entry
+ entry.setAlias(alias);
+
+ try {
+ entry.setCertificateChain(chain);
+
+ } catch (CertificateException ce) {
+ throw new KeyStoreException(ce);
+ }
+ }
+
+ } else {
+ throw new UnsupportedOperationException(
+ "Cannot assign the certificate to the given alias.");
+ }
+ }
+
+ /**
+ * Deletes the entry identified by the given alias from this keystore.
+ *
+ * @param alias the alias name
+ *
+ * @exception KeyStoreException if the entry cannot be removed.
+ */
+ public void engineDeleteEntry(String alias) throws KeyStoreException {
+ if (alias == null) {
+ throw new KeyStoreException("alias must not be null");
+ }
+
+ KeyEntry entry = entries.remove(alias);
+ if (entry != null) {
+ // Get end-entity certificate and remove from system cert store
+ X509Certificate[] certChain = entry.getCertificateChain();
+ if (certChain != null && certChain.length > 0) {
+
+ try {
+
+ byte[] encoding = certChain[0].getEncoded();
+ removeCertificate(getName(), entry.getAlias(), encoding,
+ encoding.length);
+
+ } catch (CertificateException e) {
+ throw new KeyStoreException("Cannot remove entry: ", e);
+ }
+ }
+ CKey privateKey = entry.getPrivateKey();
+ if (privateKey != null) {
+ destroyKeyContainer(
+ CKey.getContainerName(privateKey.getHCryptProvider()));
+ }
+ }
+ }
+
+ /**
+ * Lists all the alias names of this keystore.
+ *
+ * @return enumeration of the alias names
+ */
+ public Enumeration<String> engineAliases() {
+ final Iterator<String> iter = entries.keySet().iterator();
+
+ return new Enumeration<String>() {
+ public boolean hasMoreElements() {
+ return iter.hasNext();
+ }
+
+ public String nextElement() {
+ return iter.next();
+ }
+ };
+ }
+
+ /**
+ * Checks if the given alias exists in this keystore.
+ *
+ * @param alias the alias name
+ *
+ * @return true if the alias exists, false otherwise
+ */
+ public boolean engineContainsAlias(String alias) {
+ return entries.containsKey(alias);
+ }
+
+ /**
+ * Retrieves the number of entries in this keystore.
+ *
+ * @return the number of entries in this keystore
+ */
+ public int engineSize() {
+ return entries.size();
+ }
+
+ /**
+ * Returns true if the entry identified by the given alias is a
+ * <i>key entry</i>, and false otherwise.
+ *
+ * @return true if the entry identified by the given alias is a
+ * <i>key entry</i>, false otherwise.
+ */
+ public boolean engineIsKeyEntry(String alias) {
+
+ if (alias == null) {
+ return false;
+ }
+
+ KeyEntry entry = entries.get(alias);
+ return entry != null && entry.getPrivateKey() != null;
+ }
+
+ /**
+ * Returns true if the entry identified by the given alias is a
+ * <i>trusted certificate entry</i>, and false otherwise.
+ *
+ * @return true if the entry identified by the given alias is a
+ * <i>trusted certificate entry</i>, false otherwise.
+ */
+ public boolean engineIsCertificateEntry(String alias) {
+
+ if (alias == null) {
+ return false;
+ }
+
+ KeyEntry entry = entries.get(alias);
+ return entry != null && entry.getPrivateKey() == null;
+ }
+
+ /**
+ * Returns the (alias) name of the first keystore entry whose certificate
+ * matches the given certificate.
+ *
+ * <p>This method attempts to match the given certificate with each
+ * keystore entry. If the entry being considered
+ * is a <i>trusted certificate entry</i>, the given certificate is
+ * compared to that entry's certificate. If the entry being considered is
+ * a <i>key entry</i>, the given certificate is compared to the first
+ * element of that entry's certificate chain (if a chain exists).
+ *
+ * @param cert the certificate to match with.
+ *
+ * @return the (alias) name of the first entry with matching certificate,
+ * or null if no such entry exists in this keystore.
+ */
+ public String engineGetCertificateAlias(Certificate cert) {
+
+ for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) {
+ KeyEntry entry = mapEntry.getValue();
+ if (entry.certChain != null &&
+ entry.certChain.length > 0 &&
+ entry.certChain[0].equals(cert)) {
+ return entry.getAlias();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * engineStore is currently a no-op.
+ * Entries are stored during engineSetEntry.
+ *
+ * A compatibility mode is supported for applications that assume
+ * keystores are stream-based. It permits (but ignores) a non-null
+ * <code>stream</code> or <code>password</code>.
+ * The mode is enabled by default.
+ * Set the
+ * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
+ * system property to <code>false</code> to disable compatibility mode
+ * and reject a non-null <code>stream</code> or <code>password</code>.
+ *
+ * @param stream the output stream, which should be <code>null</code>
+ * @param password the password, which should be <code>null</code>
+ *
+ * @exception IOException if compatibility mode is disabled and either
+ * parameter is non-null.
+ */
+ public void engineStore(OutputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException {
+ if (stream != null && !keyStoreCompatibilityMode) {
+ throw new IOException("Keystore output stream must be null");
+ }
+
+ if (password != null && !keyStoreCompatibilityMode) {
+ throw new IOException("Keystore password must be null");
+ }
+ }
+
+ /**
+ * Loads the keystore.
+ *
+ * A compatibility mode is supported for applications that assume
+ * keystores are stream-based. It permits (but ignores) a non-null
+ * <code>stream</code> or <code>password</code>.
+ * The mode is enabled by default.
+ * Set the
+ * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
+ * system property to <code>false</code> to disable compatibility mode
+ * and reject a non-null <code>stream</code> or <code>password</code>.
+ *
+ * @param stream the input stream, which should be <code>null</code>.
+ * @param password the password, which should be <code>null</code>.
+ *
+ * @exception IOException if there is an I/O or format problem with the
+ * keystore data. Or if compatibility mode is disabled and either
+ * parameter is non-null.
+ * @exception NoSuchAlgorithmException if the algorithm used to check
+ * the integrity of the keystore cannot be found
+ * @exception CertificateException if any of the certificates in the
+ * keystore could not be loaded
+ * @exception SecurityException if the security check for
+ * <code>SecurityPermission("authProvider.<i>name</i>")</code> does not
+ * pass, where <i>name</i> is the value returned by
+ * this provider's <code>getName</code> method.
+ */
+ public void engineLoad(InputStream stream, char[] password)
+ throws IOException, NoSuchAlgorithmException, CertificateException {
+ if (stream != null && !keyStoreCompatibilityMode) {
+ throw new IOException("Keystore input stream must be null");
+ }
+
+ if (password != null && !keyStoreCompatibilityMode) {
+ throw new IOException("Keystore password must be null");
+ }
+
+ /*
+ * Use the same security check as AuthProvider.login
+ */
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new SecurityPermission(
+ "authProvider.SunMSCAPI"));
+ }
+
+ // Clear all key entries
+ entries.clear();
+
+ try {
+
+ // Load keys and/or certificate chains
+ loadKeysOrCertificateChains(getName());
+
+ } catch (KeyStoreException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Stores the given entry into the map, making sure
+ * the alias, used as the key is unique.
+ * If the same alias already exists, it tries to append
+ * a suffix (1), (2), etc to it until it finds a unique
+ * value.
+ */
+ private void storeWithUniqueAlias(String alias, KeyEntry entry) {
+ String uniqAlias = alias;
+ int uniqNum = 1;
+
+ while (true) {
+ if (entries.putIfAbsent(uniqAlias, entry) == null) {
+ break;
+ }
+ uniqAlias = alias + " (" + (uniqNum++) + ")";
+ }
+ }
+
+
+ /**
+ * Generates a certificate chain from the collection of
+ * certificates and stores the result into a key entry.
+ * <p>
+ * This method is called by native codes in security.cpp.
+ */
+ private void generateCertificateChain(String alias,
+ Collection<? extends Certificate> certCollection) {
+ try {
+ X509Certificate[] certChain =
+ new X509Certificate[certCollection.size()];
+
+ int i = 0;
+ for (Iterator<? extends Certificate> iter =
+ certCollection.iterator(); iter.hasNext(); i++) {
+ certChain[i] = (X509Certificate) iter.next();
+ }
+
+ storeWithUniqueAlias(alias,
+ new KeyEntry(alias, null, certChain));
+ } catch (Throwable e) {
+ // Ignore the exception and skip this entry
+ // TODO - throw CertificateException?
+ }
+ }
+
+ /**
+ * Generates RSA key and certificate chain from the private key handle,
+ * collection of certificates and stores the result into key entries.
+ * <p>
+ * This method is called by native codes in security.cpp.
+ */
+ private void generateRSAKeyAndCertificateChain(String alias,
+ long hCryptProv, long hCryptKey, int keyLength,
+ Collection<? extends Certificate> certCollection) {
+ try {
+ X509Certificate[] certChain =
+ new X509Certificate[certCollection.size()];
+
+ int i = 0;
+ for (Iterator<? extends Certificate> iter =
+ certCollection.iterator(); iter.hasNext(); i++) {
+ certChain[i] = (X509Certificate) iter.next();
+ }
+ storeWithUniqueAlias(alias, new KeyEntry(alias,
+ CPrivateKey.of("RSA", hCryptProv, hCryptKey, keyLength),
+ certChain));
+ } catch (Throwable e) {
+ // Ignore the exception and skip this entry
+ // TODO - throw CertificateException?
+ }
+ }
+
+ /**
+ * Generates certificates from byte data and stores into cert collection.
+ * <p>
+ * This method is called by native codes in security.cpp.
+ *
+ * @param data Byte data.
+ * @param certCollection Collection of certificates.
+ */
+ private void generateCertificate(byte[] data,
+ Collection<Certificate> certCollection) {
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+
+ // Obtain certificate factory
+ if (certificateFactory == null) {
+ certificateFactory = CertificateFactory.getInstance("X.509", "SUN");
+ }
+
+ // Generate certificate
+ Collection<? extends Certificate> c =
+ certificateFactory.generateCertificates(bis);
+ certCollection.addAll(c);
+ } catch (CertificateException e) {
+ // Ignore the exception and skip this certificate
+ // TODO - throw CertificateException?
+ } catch (Throwable te) {
+ // Ignore the exception and skip this certificate
+ // TODO - throw CertificateException?
+ }
+ }
+
+ /**
+ * Returns the name of the keystore.
+ */
+ private String getName() {
+ return storeName;
+ }
+
+ /**
+ * Load keys and/or certificates from keystore into Collection.
+ *
+ * @param name Name of keystore.
+ */
+ private native void loadKeysOrCertificateChains(String name)
+ throws KeyStoreException;
+
+ /**
+ * Stores a DER-encoded certificate into the certificate store
+ *
+ * @param name Name of the keystore.
+ * @param alias Name of the certificate.
+ * @param encoding DER-encoded certificate.
+ */
+ private native void storeCertificate(String name, String alias,
+ byte[] encoding, int encodingLength, long hCryptProvider,
+ long hCryptKey) throws CertificateException, KeyStoreException;
+
+ /**
+ * Removes the certificate from the certificate store
+ *
+ * @param name Name of the keystore.
+ * @param alias Name of the certificate.
+ * @param encoding DER-encoded certificate.
+ */
+ private native void removeCertificate(String name, String alias,
+ byte[] encoding, int encodingLength)
+ throws CertificateException, KeyStoreException;
+
+ /**
+ * Destroys the key container.
+ *
+ * @param keyContainerName The name of the key container.
+ */
+ private native void destroyKeyContainer(String keyContainerName)
+ throws KeyStoreException;
+
+ /**
+ * Generates a private-key BLOB from a key's components.
+ */
+ private native byte[] generateRSAPrivateKeyBlob(
+ int keyBitLength,
+ byte[] modulus,
+ byte[] publicExponent,
+ byte[] privateExponent,
+ byte[] primeP,
+ byte[] primeQ,
+ byte[] exponentP,
+ byte[] exponentQ,
+ byte[] crtCoefficient) throws InvalidKeyException;
+
+ private native CPrivateKey storePrivateKey(String alg, byte[] keyBlob,
+ String keyContainerName, int keySize) throws KeyStoreException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.security.PrivateKey;
+
+/**
+ * The handle for a private key using the Microsoft Crypto API.
+ *
+ * @author Stanley Man-Kit Ho
+ * @since 1.6
+ */
+class CPrivateKey extends CKey implements PrivateKey {
+
+ private static final long serialVersionUID = 8113152807912338063L;
+
+ private CPrivateKey(String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ super(alg, hCryptProv, hCryptKey, keyLength);
+ }
+
+ public static CPrivateKey of(String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ return new CPrivateKey(alg, hCryptProv, hCryptKey, keyLength);
+ }
+
+ // this key does not support encoding
+ public String getFormat() {
+ return null;
+ }
+
+ // this key does not support encoding
+ public byte[] getEncoded() {
+ return null;
+ }
+
+ public String toString() {
+ return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" +
+ getKeyType(handles.hCryptKey) + ", container=" +
+ getContainerName(handles.hCryptProv) + "]";
+ }
+
+ // This class is not serializable
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws java.io.IOException {
+ throw new java.io.NotSerializableException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.math.BigInteger;
+import java.security.KeyException;
+import java.security.KeyRep;
+import java.security.ProviderException;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
+
+import sun.security.rsa.RSAUtil.KeyType;
+import sun.security.rsa.RSAPublicKeyImpl;
+
+/**
+ * The handle for an RSA public key using the Microsoft Crypto API.
+ *
+ * @since 1.6
+ */
+public abstract class CPublicKey extends CKey implements PublicKey {
+
+ private static final long serialVersionUID = -2289561342425825391L;
+
+ protected byte[] publicKeyBlob = null;
+ protected byte[] encoding = null;
+
+ public static class CRSAPublicKey extends CPublicKey implements RSAPublicKey {
+
+ private BigInteger modulus = null;
+ private BigInteger exponent = null;
+ private static final long serialVersionUID = 12L;
+
+ CRSAPublicKey(long hCryptProv, long hCryptKey, int keyLength) {
+ super("RSA", hCryptProv, hCryptKey, keyLength);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(algorithm + "PublicKey [size=").append(keyLength)
+ .append(" bits, type=").append(getKeyType(handles.hCryptKey))
+ .append(", container=").append(getContainerName(handles.hCryptProv))
+ .append("]\n modulus: ").append(getModulus())
+ .append("\n public exponent: ").append(getPublicExponent());
+ return sb.toString();
+ }
+
+ @Override
+ public BigInteger getPublicExponent() {
+ if (exponent == null) {
+ try {
+ publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
+ exponent = new BigInteger(1, getExponent(publicKeyBlob));
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+ return exponent;
+ }
+
+ @Override
+ public BigInteger getModulus() {
+ if (modulus == null) {
+ try {
+ publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
+ modulus = new BigInteger(1, getModulus(publicKeyBlob));
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+ }
+ }
+ return modulus;
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ if (encoding == null) {
+ try {
+ encoding = RSAPublicKeyImpl.newKey(KeyType.RSA, null,
+ getModulus(), getPublicExponent()).getEncoded();
+ } catch (KeyException e) {
+ // ignore
+ }
+ }
+ return encoding;
+ }
+
+ private native byte[] getExponent(byte[] keyBlob) throws KeyException;
+
+ private native byte[] getModulus(byte[] keyBlob) throws KeyException;
+ }
+
+ public static CPublicKey of(String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ switch (alg) {
+ case "RSA":
+ return new CRSAPublicKey(hCryptProv, hCryptKey, keyLength);
+ default:
+ throw new AssertionError("Unsupported algorithm: " + alg);
+ }
+ }
+
+ protected CPublicKey(String alg, long hCryptProv, long hCryptKey, int keyLength) {
+ super(alg, hCryptProv, hCryptKey, keyLength);
+ }
+
+ @Override
+ public String getFormat() {
+ return "X.509";
+ }
+
+ protected Object writeReplace() throws java.io.ObjectStreamException {
+ return new KeyRep(KeyRep.Type.PUBLIC,
+ getAlgorithm(),
+ getFormat(),
+ getEncoded());
+ }
+
+ // Returns the Microsoft CryptoAPI representation of the key.
+ native byte[] getPublicKeyBlob(long hCryptKey) throws KeyException;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CRSACipher.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.math.BigInteger;
+import java.security.*;
+import java.security.Key;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import sun.security.rsa.RSAKeyFactory;
+import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+import sun.security.util.KeyUtil;
+
+/**
+ * Cipher implementation using the Microsoft Crypto API.
+ * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
+ *
+ * Objects should be instantiated by calling Cipher.getInstance() using the
+ * following algorithm name:
+ *
+ * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype)
+ * is selected based on the en/decryption mode and public/private key used.
+ *
+ * We only do one RSA operation per doFinal() call. If the application passes
+ * more data via calls to update() or doFinal(), we throw an
+ * IllegalBlockSizeException when doFinal() is called (see JCE API spec).
+ * Bulk encryption using RSA does not make sense and is not standardized.
+ *
+ * Note: RSA keys should be at least 512 bits long
+ *
+ * @since 1.6
+ * @author Andreas Sterbenz
+ * @author Vincent Ryan
+ */
+public final class CRSACipher extends CipherSpi {
+
+ // constant for an empty byte array
+ private final static byte[] B0 = new byte[0];
+
+ // mode constant for public key encryption
+ private final static int MODE_ENCRYPT = 1;
+ // mode constant for private key decryption
+ private final static int MODE_DECRYPT = 2;
+ // mode constant for private key encryption (signing)
+ private final static int MODE_SIGN = 3;
+ // mode constant for public key decryption (verifying)
+ private final static int MODE_VERIFY = 4;
+
+ // constant for PKCS#1 v1.5 RSA
+ private final static String PAD_PKCS1 = "PKCS1Padding";
+ private final static int PAD_PKCS1_LENGTH = 11;
+
+ // current mode, one of MODE_* above. Set when init() is called
+ private int mode;
+
+ // active padding type, one of PAD_* above. Set by setPadding()
+ private String paddingType;
+ private int paddingLength = 0;
+
+ // buffer for the data
+ private byte[] buffer;
+ // offset into the buffer (number of bytes buffered)
+ private int bufOfs;
+
+ // size of the output (the length of the key).
+ private int outputSize;
+
+ // the public key, if we were initialized using a public key
+ private CKey publicKey;
+
+ // the private key, if we were initialized using a private key
+ private CKey privateKey;
+
+ // cipher parameter for TLS RSA premaster secret
+ private AlgorithmParameterSpec spec = null;
+
+ // the source of randomness
+ private SecureRandom random;
+
+ public CRSACipher() {
+ paddingType = PAD_PKCS1;
+ }
+
+ // modes do not make sense for RSA, but allow ECB
+ // see JCE spec
+ protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+ if (mode.equalsIgnoreCase("ECB") == false) {
+ throw new NoSuchAlgorithmException("Unsupported mode " + mode);
+ }
+ }
+
+ // set the padding type
+ // see JCE spec
+ protected void engineSetPadding(String paddingName)
+ throws NoSuchPaddingException {
+ if (paddingName.equalsIgnoreCase(PAD_PKCS1)) {
+ paddingType = PAD_PKCS1;
+ } else {
+ throw new NoSuchPaddingException
+ ("Padding " + paddingName + " not supported");
+ }
+ }
+
+ // return 0 as block size, we are not a block cipher
+ // see JCE spec
+ protected int engineGetBlockSize() {
+ return 0;
+ }
+
+ // return the output size
+ // see JCE spec
+ protected int engineGetOutputSize(int inputLen) {
+ return outputSize;
+ }
+
+ // no iv, return null
+ // see JCE spec
+ protected byte[] engineGetIV() {
+ return null;
+ }
+
+ // no parameters, return null
+ // see JCE spec
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ // see JCE spec
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ init(opmode, key);
+ }
+
+ // see JCE spec
+ @SuppressWarnings("deprecation")
+ protected void engineInit(int opmode, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+
+ if (params != null) {
+ if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
+ throw new InvalidAlgorithmParameterException(
+ "Parameters not supported");
+ }
+ spec = params;
+ this.random = random; // for TLS RSA premaster secret
+ }
+ init(opmode, key);
+ }
+
+ // see JCE spec
+ protected void engineInit(int opmode, Key key,
+ AlgorithmParameters params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException
+ ("Parameters not supported");
+ }
+ init(opmode, key);
+ }
+
+ // initialize this cipher
+ private void init(int opmode, Key key) throws InvalidKeyException {
+
+ boolean encrypt;
+
+ switch (opmode) {
+ case Cipher.ENCRYPT_MODE:
+ case Cipher.WRAP_MODE:
+ paddingLength = PAD_PKCS1_LENGTH;
+ encrypt = true;
+ break;
+ case Cipher.DECRYPT_MODE:
+ case Cipher.UNWRAP_MODE:
+ paddingLength = 0; // reset
+ encrypt = false;
+ break;
+ default:
+ throw new InvalidKeyException("Unknown mode: " + opmode);
+ }
+
+ if (!(key instanceof CKey)) {
+ if (key instanceof java.security.interfaces.RSAPublicKey) {
+ java.security.interfaces.RSAPublicKey rsaKey =
+ (java.security.interfaces.RSAPublicKey) key;
+
+ // Convert key to MSCAPI format
+
+ BigInteger modulus = rsaKey.getModulus();
+ BigInteger exponent = rsaKey.getPublicExponent();
+
+ // Check against the local and global values to make sure
+ // the sizes are ok. Round up to the nearest byte.
+ RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
+ exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);
+
+ byte[] modulusBytes = modulus.toByteArray();
+ byte[] exponentBytes = exponent.toByteArray();
+
+ // Adjust key length due to sign bit
+ int keyBitLength = (modulusBytes[0] == 0)
+ ? (modulusBytes.length - 1) * 8
+ : modulusBytes.length * 8;
+
+ byte[] keyBlob = CSignature.RSA.generatePublicKeyBlob(
+ keyBitLength, modulusBytes, exponentBytes);
+
+ try {
+ key = CSignature.importPublicKey("RSA", keyBlob, keyBitLength);
+
+ } catch (KeyStoreException e) {
+ throw new InvalidKeyException(e);
+ }
+
+ } else {
+ throw new InvalidKeyException("Unsupported key type: " + key);
+ }
+ }
+
+ if (key instanceof PublicKey) {
+ mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
+ publicKey = (CKey)key;
+ privateKey = null;
+ outputSize = publicKey.length() / 8;
+ } else if (key instanceof PrivateKey) {
+ mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
+ privateKey = (CKey)key;
+ publicKey = null;
+ outputSize = privateKey.length() / 8;
+ } else {
+ throw new InvalidKeyException("Unknown key type: " + key);
+ }
+
+ bufOfs = 0;
+ buffer = new byte[outputSize];
+ }
+
+ // internal update method
+ private void update(byte[] in, int inOfs, int inLen) {
+ if ((inLen == 0) || (in == null)) {
+ return;
+ }
+ if (bufOfs + inLen > (buffer.length - paddingLength)) {
+ bufOfs = buffer.length + 1;
+ return;
+ }
+ System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
+ bufOfs += inLen;
+ }
+
+ // internal doFinal() method. Here we perform the actual RSA operation
+ private byte[] doFinal() throws BadPaddingException,
+ IllegalBlockSizeException {
+ if (bufOfs > buffer.length) {
+ throw new IllegalBlockSizeException("Data must not be longer "
+ + "than " + (buffer.length - paddingLength) + " bytes");
+ }
+
+ try {
+ byte[] data = buffer;
+ switch (mode) {
+ case MODE_SIGN:
+ return encryptDecrypt(data, bufOfs,
+ privateKey.getHCryptKey(), true);
+
+ case MODE_VERIFY:
+ return encryptDecrypt(data, bufOfs,
+ publicKey.getHCryptKey(), false);
+
+ case MODE_ENCRYPT:
+ return encryptDecrypt(data, bufOfs,
+ publicKey.getHCryptKey(), true);
+
+ case MODE_DECRYPT:
+ return encryptDecrypt(data, bufOfs,
+ privateKey.getHCryptKey(), false);
+
+ default:
+ throw new AssertionError("Internal error");
+ }
+
+ } catch (KeyException e) {
+ throw new ProviderException(e);
+
+ } finally {
+ bufOfs = 0;
+ }
+ }
+
+ // see JCE spec
+ protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
+ update(in, inOfs, inLen);
+ return B0;
+ }
+
+ // see JCE spec
+ protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
+ int outOfs) {
+ update(in, inOfs, inLen);
+ return 0;
+ }
+
+ // see JCE spec
+ protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
+ throws BadPaddingException, IllegalBlockSizeException {
+ update(in, inOfs, inLen);
+ return doFinal();
+ }
+
+ // see JCE spec
+ protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
+ int outOfs) throws ShortBufferException, BadPaddingException,
+ IllegalBlockSizeException {
+ if (outputSize > out.length - outOfs) {
+ throw new ShortBufferException
+ ("Need " + outputSize + " bytes for output");
+ }
+ update(in, inOfs, inLen);
+ byte[] result = doFinal();
+ int n = result.length;
+ System.arraycopy(result, 0, out, outOfs, n);
+ return n;
+ }
+
+ // see JCE spec
+ protected byte[] engineWrap(Key key) throws InvalidKeyException,
+ IllegalBlockSizeException {
+ byte[] encoded = key.getEncoded(); // TODO - unextractable key
+ if ((encoded == null) || (encoded.length == 0)) {
+ throw new InvalidKeyException("Could not obtain encoded key");
+ }
+ if (encoded.length > buffer.length) {
+ throw new InvalidKeyException("Key is too long for wrapping");
+ }
+ update(encoded, 0, encoded.length);
+ try {
+ return doFinal();
+ } catch (BadPaddingException e) {
+ // should not occur
+ throw new InvalidKeyException("Wrapping failed", e);
+ }
+ }
+
+ // see JCE spec
+ @SuppressWarnings("deprecation")
+ protected java.security.Key engineUnwrap(byte[] wrappedKey,
+ String algorithm,
+ int type) throws InvalidKeyException, NoSuchAlgorithmException {
+
+ if (wrappedKey.length > buffer.length) {
+ throw new InvalidKeyException("Key is too long for unwrapping");
+ }
+
+ boolean isTlsRsaPremasterSecret =
+ algorithm.equals("TlsRsaPremasterSecret");
+ Exception failover = null;
+ byte[] encoded = null;
+
+ update(wrappedKey, 0, wrappedKey.length);
+ try {
+ encoded = doFinal();
+ } catch (BadPaddingException e) {
+ if (isTlsRsaPremasterSecret) {
+ failover = e;
+ } else {
+ throw new InvalidKeyException("Unwrapping failed", e);
+ }
+ } catch (IllegalBlockSizeException e) {
+ // should not occur, handled with length check above
+ throw new InvalidKeyException("Unwrapping failed", e);
+ }
+
+ if (isTlsRsaPremasterSecret) {
+ if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
+ throw new IllegalStateException(
+ "No TlsRsaPremasterSecretParameterSpec specified");
+ }
+
+ // polish the TLS premaster secret
+ encoded = KeyUtil.checkTlsPreMasterSecretKey(
+ ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
+ ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
+ random, encoded, (failover != null));
+ }
+
+ return constructKey(encoded, algorithm, type);
+ }
+
+ // see JCE spec
+ protected int engineGetKeySize(Key key) throws InvalidKeyException {
+
+ if (key instanceof CKey) {
+ return ((CKey) key).length();
+
+ } else if (key instanceof RSAKey) {
+ return ((RSAKey) key).getModulus().bitLength();
+
+ } else {
+ throw new InvalidKeyException("Unsupported key type: " + key);
+ }
+ }
+
+ // Construct an X.509 encoded public key.
+ private static PublicKey constructPublicKey(byte[] encodedKey,
+ String encodedKeyAlgorithm)
+ throws InvalidKeyException, NoSuchAlgorithmException {
+
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
+
+ return keyFactory.generatePublic(keySpec);
+
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new NoSuchAlgorithmException("No installed provider " +
+ "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
+
+ } catch (InvalidKeySpecException ike) {
+ throw new InvalidKeyException("Cannot construct public key", ike);
+ }
+ }
+
+ // Construct a PKCS #8 encoded private key.
+ private static PrivateKey constructPrivateKey(byte[] encodedKey,
+ String encodedKeyAlgorithm)
+ throws InvalidKeyException, NoSuchAlgorithmException {
+
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
+
+ return keyFactory.generatePrivate(keySpec);
+
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new NoSuchAlgorithmException("No installed provider " +
+ "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
+
+ } catch (InvalidKeySpecException ike) {
+ throw new InvalidKeyException("Cannot construct private key", ike);
+ }
+ }
+
+ // Construct an encoded secret key.
+ private static SecretKey constructSecretKey(byte[] encodedKey,
+ String encodedKeyAlgorithm) {
+
+ return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
+ }
+
+ private static Key constructKey(byte[] encodedKey,
+ String encodedKeyAlgorithm,
+ int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
+
+ switch (keyType) {
+ case Cipher.PUBLIC_KEY:
+ return constructPublicKey(encodedKey, encodedKeyAlgorithm);
+ case Cipher.PRIVATE_KEY:
+ return constructPrivateKey(encodedKey, encodedKeyAlgorithm);
+ case Cipher.SECRET_KEY:
+ return constructSecretKey(encodedKey, encodedKeyAlgorithm);
+ default:
+ throw new InvalidKeyException("Unknown key type " + keyType);
+ }
+ }
+
+ /*
+ * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY.
+ * It expects and returns ciphertext data in big-endian form.
+ */
+ private native static byte[] encryptDecrypt(byte[] data, int dataSize,
+ long hCryptKey, boolean doEncrypt) throws KeyException;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CSignature.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.mscapi;
+
+import java.nio.ByteBuffer;
+import java.security.*;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.math.BigInteger;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.util.Locale;
+
+import sun.security.rsa.RSAKeyFactory;
+
+/**
+ * Signature implementation. Supports RSA signing using PKCS#1 v1.5 padding
+ * and RSASSA-PSS signing.
+ *
+ * Objects should be instantiated by calling Signature.getInstance() using the
+ * following algorithm names:
+ *
+ * . "NONEwithRSA"
+ * . "SHA1withRSA"
+ * . "SHA256withRSA"
+ * . "SHA384withRSA"
+ * . "SHA512withRSA"
+ * . "MD5withRSA"
+ * . "MD2withRSA"
+ * . "RSASSA-PSS"
+ *
+ * NOTE: RSA keys must be at least 512 bits long.
+ *
+ * NOTE: NONEwithRSA must be supplied with a pre-computed message digest.
+ * Only the following digest algorithms are supported: MD5, SHA-1,
+ * SHA-256, SHA-384, SHA-512 and a special-purpose digest
+ * algorithm which is a concatenation of SHA-1 and MD5 digests.
+ *
+ * @since 1.6
+ * @author Stanley Man-Kit Ho
+ */
+abstract class CSignature extends SignatureSpi {
+ // private key algorithm name
+ protected String keyAlgorithm;
+
+ // message digest implementation we use
+ protected MessageDigest messageDigest;
+
+ // message digest name
+ protected String messageDigestAlgorithm;
+
+ // flag indicating whether the digest has been reset
+ protected boolean needsReset;
+
+ // the signing key
+ protected CPrivateKey privateKey = null;
+
+ // the verification key
+ protected CPublicKey publicKey = null;
+
+ /**
+ * Constructs a new CSignature. Used by subclasses.
+ */
+ CSignature(String keyName, String digestName) {
+
+ this.keyAlgorithm = keyName;
+ if (digestName != null) {
+ try {
+ messageDigest = MessageDigest.getInstance(digestName);
+ // Get the digest's canonical name
+ messageDigestAlgorithm = messageDigest.getAlgorithm();
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(e);
+ }
+ } else {
+ messageDigest = null;
+ messageDigestAlgorithm = null;
+ }
+ needsReset = false;
+ }
+
+ static class RSA extends CSignature {
+
+ public RSA(String digestAlgorithm) {
+ super("RSA", digestAlgorithm);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
+
+ if ((key instanceof CPrivateKey) == false) {
+ throw new InvalidKeyException("Key type not supported");
+ }
+ privateKey = (CPrivateKey) key;
+
+ // Check against the local and global values to make sure
+ // the sizes are ok. Round up to nearest byte.
+ RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
+ null, CKeyPairGenerator.RSA.KEY_SIZE_MIN,
+ CKeyPairGenerator.RSA.KEY_SIZE_MAX);
+
+ this.publicKey = null;
+ resetDigest();
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
+ // This signature accepts only RSAPublicKey
+ if ((key instanceof RSAPublicKey) == false) {
+ throw new InvalidKeyException("Key type not supported");
+ }
+
+
+ if ((key instanceof CPublicKey) == false) {
+
+ // convert key to MSCAPI format
+ java.security.interfaces.RSAPublicKey rsaKey =
+ (java.security.interfaces.RSAPublicKey) key;
+
+ BigInteger modulus = rsaKey.getModulus();
+ BigInteger exponent = rsaKey.getPublicExponent();
+
+ // Check against the local and global values to make sure
+ // the sizes are ok. Round up to the nearest byte.
+ RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
+ exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);
+
+ byte[] modulusBytes = modulus.toByteArray();
+ byte[] exponentBytes = exponent.toByteArray();
+
+ // Adjust key length due to sign bit
+ int keyBitLength = (modulusBytes[0] == 0)
+ ? (modulusBytes.length - 1) * 8
+ : modulusBytes.length * 8;
+
+ byte[] keyBlob = generatePublicKeyBlob(
+ keyBitLength, modulusBytes, exponentBytes);
+
+ try {
+ publicKey = importPublicKey("RSA", keyBlob, keyBitLength);
+
+ } catch (KeyStoreException e) {
+ throw new InvalidKeyException(e);
+ }
+
+ } else {
+ publicKey = (CPublicKey) key;
+ }
+
+ this.privateKey = null;
+ resetDigest();
+ }
+
+ /**
+ * Returns the signature bytes of all the data
+ * updated so far.
+ * The format of the signature depends on the underlying
+ * signature scheme.
+ *
+ * @return the signature bytes of the signing operation's result.
+ *
+ * @exception SignatureException if the engine is not
+ * initialized properly or if this signature algorithm is unable to
+ * process the input data provided.
+ */
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+
+ byte[] hash = getDigestValue();
+
+ // Omit the hash OID when generating a NONEwithRSA signature
+ boolean noHashOID = this instanceof NONEwithRSA;
+
+ // Sign hash using MS Crypto APIs
+
+ byte[] result = signHash(noHashOID, hash, hash.length,
+ messageDigestAlgorithm, privateKey.getHCryptProvider(),
+ privateKey.getHCryptKey());
+
+ // Convert signature array from little endian to big endian
+ return convertEndianArray(result);
+ }
+
+ /**
+ * Verifies the passed-in signature.
+ *
+ * @param sigBytes the signature bytes to be verified.
+ *
+ * @return true if the signature was verified, false if not.
+ *
+ * @exception SignatureException if the engine is not
+ * initialized properly, the passed-in signature is improperly
+ * encoded or of the wrong type, if this signature algorithm is unable to
+ * process the input data provided, etc.
+ */
+ @Override
+ protected boolean engineVerify(byte[] sigBytes)
+ throws SignatureException {
+ byte[] hash = getDigestValue();
+
+ return verifySignedHash(hash, hash.length,
+ messageDigestAlgorithm, convertEndianArray(sigBytes),
+ sigBytes.length, publicKey.getHCryptProvider(),
+ publicKey.getHCryptKey());
+ }
+
+ /**
+ * Generates a public-key BLOB from a key's components.
+ */
+ // used by CRSACipher
+ static native byte[] generatePublicKeyBlob(
+ int keyBitLength, byte[] modulus, byte[] publicExponent)
+ throws InvalidKeyException;
+
+ }
+
+ // Nested class for NONEwithRSA signatures
+ public static final class NONEwithRSA extends RSA {
+
+ // the longest supported digest is 512 bits (SHA-512)
+ private static final int RAW_RSA_MAX = 64;
+
+ private final byte[] precomputedDigest;
+ private int offset = 0;
+
+ public NONEwithRSA() {
+ super(null);
+ precomputedDigest = new byte[RAW_RSA_MAX];
+ }
+
+ // Stores the precomputed message digest value.
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ if (offset >= precomputedDigest.length) {
+ offset = RAW_RSA_MAX + 1;
+ return;
+ }
+ precomputedDigest[offset++] = b;
+ }
+
+ // Stores the precomputed message digest value.
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ if (len > (precomputedDigest.length - offset)) {
+ offset = RAW_RSA_MAX + 1;
+ return;
+ }
+ System.arraycopy(b, off, precomputedDigest, offset, len);
+ offset += len;
+ }
+
+ // Stores the precomputed message digest value.
+ @Override
+ protected void engineUpdate(ByteBuffer byteBuffer) {
+ int len = byteBuffer.remaining();
+ if (len <= 0) {
+ return;
+ }
+ if (len > (precomputedDigest.length - offset)) {
+ offset = RAW_RSA_MAX + 1;
+ return;
+ }
+ byteBuffer.get(precomputedDigest, offset, len);
+ offset += len;
+ }
+
+ @Override
+ protected void resetDigest(){
+ offset = 0;
+ }
+
+ // Returns the precomputed message digest value.
+ @Override
+ protected byte[] getDigestValue() throws SignatureException {
+ if (offset > RAW_RSA_MAX) {
+ throw new SignatureException("Message digest is too long");
+ }
+
+ // Determine the digest algorithm from the digest length
+ if (offset == 20) {
+ setDigestName("SHA1");
+ } else if (offset == 36) {
+ setDigestName("SHA1+MD5");
+ } else if (offset == 32) {
+ setDigestName("SHA-256");
+ } else if (offset == 48) {
+ setDigestName("SHA-384");
+ } else if (offset == 64) {
+ setDigestName("SHA-512");
+ } else if (offset == 16) {
+ setDigestName("MD5");
+ } else {
+ throw new SignatureException(
+ "Message digest length is not supported");
+ }
+
+ byte[] result = new byte[offset];
+ System.arraycopy(precomputedDigest, 0, result, 0, offset);
+ offset = 0;
+
+ return result;
+ }
+ }
+
+ public static final class SHA1withRSA extends RSA {
+ public SHA1withRSA() {
+ super("SHA1");
+ }
+ }
+
+ public static final class SHA256withRSA extends RSA {
+ public SHA256withRSA() {
+ super("SHA-256");
+ }
+ }
+
+ public static final class SHA384withRSA extends RSA {
+ public SHA384withRSA() {
+ super("SHA-384");
+ }
+ }
+
+ public static final class SHA512withRSA extends RSA {
+ public SHA512withRSA() {
+ super("SHA-512");
+ }
+ }
+
+ public static final class MD5withRSA extends RSA {
+ public MD5withRSA() {
+ super("MD5");
+ }
+ }
+
+ public static final class MD2withRSA extends RSA {
+ public MD2withRSA() {
+ super("MD2");
+ }
+ }
+
+ public static final class PSS extends RSA {
+
+ private PSSParameterSpec pssParams = null;
+
+ // Workaround: Cannot import raw public key to CNG. This signature
+ // will be used for verification if key is not from MSCAPI.
+ private Signature fallbackSignature;
+
+ public PSS() {
+ super(null);
+ }
+
+ @Override
+ protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
+ super.engineInitSign(key);
+ fallbackSignature = null;
+ }
+
+ @Override
+ protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
+ // This signature accepts only RSAPublicKey
+ if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {
+ throw new InvalidKeyException("Key type not supported");
+ }
+
+ this.privateKey = null;
+
+ if (key instanceof CPublicKey) {
+ fallbackSignature = null;
+ publicKey = (CPublicKey) key;
+ } else {
+ if (fallbackSignature == null) {
+ try {
+ fallbackSignature = Signature.getInstance(
+ "RSASSA-PSS", "SunRsaSign");
+ } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+ throw new InvalidKeyException("Invalid key", e);
+ }
+ }
+ fallbackSignature.initVerify(key);
+ if (pssParams != null) {
+ try {
+ fallbackSignature.setParameter(pssParams);
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidKeyException("Invalid params", e);
+ }
+ }
+ publicKey = null;
+ }
+ resetDigest();
+ }
+
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ ensureInit();
+ if (fallbackSignature != null) {
+ fallbackSignature.update(b);
+ } else {
+ messageDigest.update(b);
+ }
+ needsReset = true;
+ }
+
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ ensureInit();
+ if (fallbackSignature != null) {
+ fallbackSignature.update(b, off, len);
+ } else {
+ messageDigest.update(b, off, len);
+ }
+ needsReset = true;
+ }
+
+ @Override
+ protected void engineUpdate(ByteBuffer input) {
+ try {
+ ensureInit();
+ } catch (SignatureException se) {
+ // hack for working around API bug
+ throw new RuntimeException(se.getMessage());
+ }
+ if (fallbackSignature != null) {
+ try {
+ fallbackSignature.update(input);
+ } catch (SignatureException se) {
+ // hack for working around API bug
+ throw new RuntimeException(se.getMessage());
+ }
+ } else {
+ messageDigest.update(input);
+ }
+ needsReset = true;
+ }
+
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ ensureInit();
+ byte[] hash = getDigestValue();
+ return signCngHash(hash, hash.length,
+ pssParams.getSaltLength(),
+ ((MGF1ParameterSpec)
+ pssParams.getMGFParameters()).getDigestAlgorithm(),
+ privateKey.getHCryptProvider(), privateKey.getHCryptKey());
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ ensureInit();
+ if (fallbackSignature != null) {
+ needsReset = false;
+ return fallbackSignature.verify(sigBytes);
+ } else {
+ byte[] hash = getDigestValue();
+ return verifyCngSignedHash(
+ hash, hash.length,
+ sigBytes, sigBytes.length,
+ pssParams.getSaltLength(),
+ ((MGF1ParameterSpec)
+ pssParams.getMGFParameters()).getDigestAlgorithm(),
+ publicKey.getHCryptProvider(),
+ publicKey.getHCryptKey()
+ );
+ }
+ }
+
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (needsReset) {
+ throw new ProviderException
+ ("Cannot set parameters during operations");
+ }
+ this.pssParams = validateSigParams(params);
+ if (fallbackSignature != null) {
+ fallbackSignature.setParameter(params);
+ }
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ AlgorithmParameters ap = null;
+ if (this.pssParams != null) {
+ try {
+ ap = AlgorithmParameters.getInstance("RSASSA-PSS");
+ ap.init(this.pssParams);
+ } catch (GeneralSecurityException gse) {
+ throw new ProviderException(gse.getMessage());
+ }
+ }
+ return ap;
+ }
+
+ private void ensureInit() throws SignatureException {
+ if (this.privateKey == null && this.publicKey == null
+ && fallbackSignature == null) {
+ throw new SignatureException("Missing key");
+ }
+ if (this.pssParams == null) {
+ // Parameters are required for signature verification
+ throw new SignatureException
+ ("Parameters required for RSASSA-PSS signatures");
+ }
+ if (fallbackSignature == null && messageDigest == null) {
+ // This could happen if initVerify(softKey), setParameter(),
+ // and initSign() were called. No messageDigest. Create it.
+ try {
+ messageDigest = MessageDigest
+ .getInstance(pssParams.getDigestAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new SignatureException(e);
+ }
+ }
+ }
+
+ /**
+ * Validate the specified Signature PSS parameters.
+ */
+ private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
+ throws InvalidAlgorithmParameterException {
+
+ if (p == null) {
+ throw new InvalidAlgorithmParameterException
+ ("Parameters cannot be null");
+ }
+
+ if (!(p instanceof PSSParameterSpec)) {
+ throw new InvalidAlgorithmParameterException
+ ("parameters must be type PSSParameterSpec");
+ }
+
+ // no need to validate again if same as current signature parameters
+ PSSParameterSpec params = (PSSParameterSpec) p;
+ if (params == this.pssParams) return params;
+
+ // now sanity check the parameter values
+ if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
+ throw new InvalidAlgorithmParameterException("Only supports MGF1");
+
+ }
+
+ if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
+ throw new InvalidAlgorithmParameterException
+ ("Only supports TrailerFieldBC(1)");
+ }
+
+ AlgorithmParameterSpec algSpec = params.getMGFParameters();
+ if (!(algSpec instanceof MGF1ParameterSpec)) {
+ throw new InvalidAlgorithmParameterException
+ ("Only support MGF1ParameterSpec");
+ }
+
+ MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)algSpec;
+
+ String msgHashAlg = params.getDigestAlgorithm()
+ .toLowerCase(Locale.ROOT).replaceAll("-", "");
+ if (msgHashAlg.equals("sha")) {
+ msgHashAlg = "sha1";
+ }
+ String mgf1HashAlg = mgfSpec.getDigestAlgorithm()
+ .toLowerCase(Locale.ROOT).replaceAll("-", "");
+ if (mgf1HashAlg.equals("sha")) {
+ mgf1HashAlg = "sha1";
+ }
+
+ if (!mgf1HashAlg.equals(msgHashAlg)) {
+ throw new InvalidAlgorithmParameterException
+ ("MGF1 hash must be the same as message hash");
+ }
+
+ return params;
+ }
+ }
+
+ /**
+ * Sign hash using CNG API with HCRYPTKEY. Used by RSASSA-PSS.
+ */
+ native static byte[] signCngHash(
+ byte[] hash, int hashSize, int saltLength, String hashAlgorithm,
+ long hCryptProv, long nCryptKey)
+ throws SignatureException;
+
+ /**
+ * Verify a signed hash using CNG API with HCRYPTKEY. Used by RSASSA-PSS.
+ * This method is not used now. See {@link PSS#fallbackSignature}.
+ */
+ private native static boolean verifyCngSignedHash(
+ byte[] hash, int hashSize, byte[] signature, int signatureSize,
+ int saltLength, String hashAlgorithm,
+ long hCryptProv, long hKey) throws SignatureException;
+
+ /**
+ * Resets the message digest if needed.
+ */
+ protected void resetDigest() {
+ if (needsReset) {
+ if (messageDigest != null) {
+ messageDigest.reset();
+ }
+ needsReset = false;
+ }
+ }
+
+ protected byte[] getDigestValue() throws SignatureException {
+ needsReset = false;
+ return messageDigest.digest();
+ }
+
+ protected void setDigestName(String name) {
+ messageDigestAlgorithm = name;
+ }
+
+ /**
+ * Updates the data to be signed or verified
+ * using the specified byte.
+ *
+ * @param b the byte to use for the update.
+ *
+ * @exception SignatureException if the engine is not initialized
+ * properly.
+ */
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ messageDigest.update(b);
+ needsReset = true;
+ }
+
+ /**
+ * Updates the data to be signed or verified, using the
+ * specified array of bytes, starting at the specified offset.
+ *
+ * @param b the array of bytes
+ * @param off the offset to start from in the array of bytes
+ * @param len the number of bytes to use, starting at offset
+ *
+ * @exception SignatureException if the engine is not initialized
+ * properly
+ */
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ messageDigest.update(b, off, len);
+ needsReset = true;
+ }
+
+ /**
+ * Updates the data to be signed or verified, using the
+ * specified ByteBuffer.
+ *
+ * @param input the ByteBuffer
+ */
+ @Override
+ protected void engineUpdate(ByteBuffer input) {
+ messageDigest.update(input);
+ needsReset = true;
+ }
+
+ /**
+ * Convert array from big endian to little endian, or vice versa.
+ */
+ private static byte[] convertEndianArray(byte[] byteArray) {
+ if (byteArray == null || byteArray.length == 0)
+ return byteArray;
+
+ byte [] retval = new byte[byteArray.length];
+
+ // make it big endian
+ for (int i=0;i < byteArray.length;i++)
+ retval[i] = byteArray[byteArray.length - i - 1];
+
+ return retval;
+ }
+
+ /**
+ * Sign hash using Microsoft Crypto API with HCRYPTKEY.
+ * The returned data is in little-endian.
+ */
+ private native static byte[] signHash(boolean noHashOID, byte[] hash,
+ int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)
+ throws SignatureException;
+
+ /**
+ * Verify a signed hash using Microsoft Crypto API with HCRYPTKEY.
+ */
+ private native static boolean verifySignedHash(byte[] hash, int hashSize,
+ String hashAlgorithm, byte[] signature, int signatureSize,
+ long hCryptProv, long hCryptKey) throws SignatureException;
+
+ /**
+ * Sets the specified algorithm parameter to the specified
+ * value. This method supplies a general-purpose mechanism through
+ * which it is possible to set the various parameters of this object.
+ * A parameter may be any settable parameter for the algorithm, such as
+ * a parameter size, or a source of random bits for signature generation
+ * (if appropriate), or an indication of whether or not to perform
+ * a specific but optional computation. A uniform algorithm-specific
+ * naming scheme for each parameter is desirable but left unspecified
+ * at this time.
+ *
+ * @param param the string identifier of the parameter.
+ *
+ * @param value the parameter value.
+ *
+ * @exception InvalidParameterException if <code>param</code> is an
+ * invalid parameter for this signature algorithm engine,
+ * the parameter is already set
+ * and cannot be set again, a security exception occurs, and so on.
+ *
+ * @deprecated Replaced by {@link
+ * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
+ * engineSetParameter}.
+ */
+ @Override
+ @Deprecated
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ throw new InvalidParameterException("Parameter not supported");
+ }
+
+ /**
+ * Sets this signature engine with the specified algorithm parameter.
+ *
+ * @param params the parameters
+ *
+ * @exception InvalidAlgorithmParameterException if the given
+ * parameter is invalid
+ */
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameter accepted");
+ }
+ }
+
+ /**
+ * Gets the value of the specified algorithm parameter.
+ * This method supplies a general-purpose mechanism through which it
+ * is possible to get the various parameters of this object. A parameter
+ * may be any settable parameter for the algorithm, such as a parameter
+ * size, or a source of random bits for signature generation (if
+ * appropriate), or an indication of whether or not to perform a
+ * specific but optional computation. A uniform algorithm-specific
+ * naming scheme for each parameter is desirable but left unspecified
+ * at this time.
+ *
+ * @param param the string name of the parameter.
+ *
+ * @return the object that represents the parameter value, or null if
+ * there is none.
+ *
+ * @exception InvalidParameterException if <code>param</code> is an
+ * invalid parameter for this engine, or another exception occurs while
+ * trying to get this parameter.
+ *
+ * @deprecated
+ */
+ @Override
+ @Deprecated
+ protected Object engineGetParameter(String param)
+ throws InvalidParameterException {
+ throw new InvalidParameterException("Parameter not supported");
+ }
+
+ /**
+ * Gets the algorithm parameter from this signature engine.
+ *
+ * @return the parameter, or null if no parameter is used.
+ */
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ /**
+ * Imports a public-key BLOB.
+ */
+ // used by CRSACipher
+ static native CPublicKey importPublicKey(
+ String alg, byte[] keyBlob, int keySize) throws KeyStoreException;
+}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import sun.security.util.Length;
-
-/**
- * The handle for an RSA or DSA key using the Microsoft Crypto API.
- *
- * @see RSAPrivateKey
- * @see RSAPublicKey
- *
- * @since 1.6
- * @author Stanley Man-Kit Ho
- */
-abstract class Key implements java.security.Key, Length
-{
- private static final long serialVersionUID = -1088859394025049194L;
-
- static class NativeHandles {
- long hCryptProv = 0;
- long hCryptKey = 0;
-
- public NativeHandles(long hCryptProv, long hCryptKey) {
- this.hCryptProv = hCryptProv;
- this.hCryptKey = hCryptKey;
- }
-
- /**
- * Finalization method
- */
- @SuppressWarnings("deprecation")
- protected void finalize() throws Throwable
- {
- try {
- synchronized(this)
- {
- cleanUp(hCryptProv, hCryptKey);
- hCryptProv = 0;
- hCryptKey = 0;
- }
-
- } finally {
- super.finalize();
- }
- }
- }
-
- protected NativeHandles handles;
-
- // Key length
- protected int keyLength = 0;
-
- /**
- * Construct a Key object.
- */
- protected Key(NativeHandles handles, int keyLength)
- {
- this.handles = handles;
- this.keyLength = keyLength;
- }
-
- /**
- * Native method to cleanup the key handle.
- */
- private native static void cleanUp(long hCryptProv, long hCryptKey);
-
- /**
- * Return bit length of the key.
- */
- @Override
- public int length()
- {
- return keyLength;
- }
-
-
- /**
- * Return native HCRYPTKEY handle.
- */
- public long getHCryptKey()
- {
- return handles.hCryptKey;
- }
-
- /**
- * Return native HCRYPTPROV handle.
- */
- public long getHCryptProvider()
- {
- return handles.hCryptProv;
- }
-
- /**
- * Returns the standard algorithm name for this key. For
- * example, "RSA" would indicate that this key is a RSA key.
- * See Appendix A in the <a href=
- * "../../../guide/security/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for information about standard algorithm names.
- *
- * @return the name of the algorithm associated with this key.
- */
- public abstract String getAlgorithm();
-
- /**
- * Returns the name of the primary encoding format of this key,
- * or null if this key does not support encoding.
- * The primary encoding format is
- * named in terms of the appropriate ASN.1 data format, if an
- * ASN.1 specification for this key exists.
- * For example, the name of the ASN.1 data format for public
- * keys is <I>SubjectPublicKeyInfo</I>, as
- * defined by the X.509 standard; in this case, the returned format is
- * <code>"X.509"</code>. Similarly,
- * the name of the ASN.1 data format for private keys is
- * <I>PrivateKeyInfo</I>,
- * as defined by the PKCS #8 standard; in this case, the returned format is
- * <code>"PKCS#8"</code>.
- *
- * @return the primary encoding format of the key.
- */
- public String getFormat()
- {
- return null;
- }
-
- /**
- * Returns the key in its primary encoding format, or null
- * if this key does not support encoding.
- *
- * @return the encoded key, or null if the key does not support
- * encoding.
- */
- public byte[] getEncoded()
- {
- return null;
- }
-
- protected native static String getContainerName(long hCryptProv);
-
- protected native static String getKeyType(long hCryptKey);
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,910 +0,0 @@
-/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.AccessController;
-import java.security.InvalidKeyException;
-import java.security.KeyStoreSpi;
-import java.security.KeyStoreException;
-import java.security.PrivilegedAction;
-import java.security.UnrecoverableKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecurityPermission;
-import java.security.cert.X509Certificate;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.util.*;
-
-/**
- * Implementation of key store for Windows using the Microsoft Crypto API.
- *
- * @since 1.6
- */
-abstract class KeyStore extends KeyStoreSpi {
-
- public static final class MY extends KeyStore {
- public MY() {
- super("MY");
- }
- }
-
- public static final class ROOT extends KeyStore {
- public ROOT() {
- super("ROOT");
- }
- }
-
- class KeyEntry
- {
- private Key privateKey;
- private X509Certificate[] certChain;
- private String alias;
-
- KeyEntry(Key key, X509Certificate[] chain) {
- this(null, key, chain);
- }
-
- KeyEntry(String alias, Key key, X509Certificate[] chain) {
- this.privateKey = key;
- this.certChain = chain;
- /*
- * The default alias for both entry types is derived from a
- * hash value intrinsic to the first certificate in the chain.
- */
- if (alias == null) {
- this.alias = Integer.toString(chain[0].hashCode());
- } else {
- this.alias = alias;
- }
- }
-
- /**
- * Gets the alias for the keystore entry.
- */
- String getAlias()
- {
- return alias;
- }
-
- /**
- * Sets the alias for the keystore entry.
- */
- void setAlias(String alias)
- {
- // TODO - set friendly name prop in cert store
- this.alias = alias;
- }
-
- /**
- * Gets the private key for the keystore entry.
- */
- Key getPrivateKey()
- {
- return privateKey;
- }
-
- /**
- * Sets the private key for the keystore entry.
- */
- void setPrivateKey(RSAPrivateCrtKey key)
- throws InvalidKeyException, KeyStoreException
- {
- byte[] modulusBytes = key.getModulus().toByteArray();
-
- // Adjust key length due to sign bit
- int keyBitLength = (modulusBytes[0] == 0)
- ? (modulusBytes.length - 1) * 8
- : modulusBytes.length * 8;
-
- byte[] keyBlob = generatePrivateKeyBlob(
- keyBitLength,
- modulusBytes,
- key.getPublicExponent().toByteArray(),
- key.getPrivateExponent().toByteArray(),
- key.getPrimeP().toByteArray(),
- key.getPrimeQ().toByteArray(),
- key.getPrimeExponentP().toByteArray(),
- key.getPrimeExponentQ().toByteArray(),
- key.getCrtCoefficient().toByteArray());
-
- privateKey = storePrivateKey(Objects.requireNonNull(keyBlob),
- "{" + UUID.randomUUID().toString() + "}", keyBitLength);
- }
-
- /**
- * Gets the certificate chain for the keystore entry.
- */
- X509Certificate[] getCertificateChain()
- {
- return certChain;
- }
-
- /**
- * Sets the certificate chain for the keystore entry.
- */
- void setCertificateChain(X509Certificate[] chain)
- throws CertificateException, KeyStoreException
- {
- for (int i = 0; i < chain.length; i++) {
- byte[] encoding = chain[i].getEncoded();
- if (i == 0 && privateKey != null) {
- storeCertificate(getName(), alias, encoding,
- encoding.length, privateKey.getHCryptProvider(),
- privateKey.getHCryptKey());
-
- } else {
- storeCertificate(getName(), alias, encoding,
- encoding.length, 0L, 0L); // no private key to attach
- }
- }
- certChain = chain;
- }
- }
-
- /*
- * An X.509 certificate factory.
- * Used to create an X.509 certificate from its DER-encoding.
- */
- private CertificateFactory certificateFactory = null;
-
- /*
- * Compatibility mode: for applications that assume keystores are
- * stream-based this mode tolerates (but ignores) a non-null stream
- * or password parameter when passed to the load or store methods.
- * The mode is enabled by default.
- */
- private static final String KEYSTORE_COMPATIBILITY_MODE_PROP =
- "sun.security.mscapi.keyStoreCompatibilityMode";
- private final boolean keyStoreCompatibilityMode;
-
- /*
- * The keystore entries.
- * Keys in the map are unique aliases (thus can differ from
- * KeyEntry.getAlias())
- */
- private Map<String,KeyEntry> entries = new HashMap<>();
-
- /*
- * The keystore name.
- * Case is not significant.
- */
- private final String storeName;
-
- KeyStore(String storeName) {
- // Get the compatibility mode
- String prop = AccessController.doPrivileged(
- (PrivilegedAction<String>) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP));
-
- if ("false".equalsIgnoreCase(prop)) {
- keyStoreCompatibilityMode = false;
- } else {
- keyStoreCompatibilityMode = true;
- }
-
- this.storeName = storeName;
- }
-
- /**
- * Returns the key associated with the given alias.
- * <p>
- * A compatibility mode is supported for applications that assume
- * a password must be supplied. It permits (but ignores) a non-null
- * <code>password</code>. The mode is enabled by default.
- * Set the
- * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
- * system property to <code>false</code> to disable compatibility mode
- * and reject a non-null <code>password</code>.
- *
- * @param alias the alias name
- * @param password the password, which should be <code>null</code>
- *
- * @return the requested key, or null if the given alias does not exist
- * or does not identify a <i>key entry</i>.
- *
- * @exception NoSuchAlgorithmException if the algorithm for recovering the
- * key cannot be found,
- * or if compatibility mode is disabled and <code>password</code> is
- * non-null.
- * @exception UnrecoverableKeyException if the key cannot be recovered.
- */
- public java.security.Key engineGetKey(String alias, char[] password)
- throws NoSuchAlgorithmException, UnrecoverableKeyException
- {
- if (alias == null) {
- return null;
- }
-
- if (password != null && !keyStoreCompatibilityMode) {
- throw new UnrecoverableKeyException("Password must be null");
- }
-
- if (engineIsKeyEntry(alias) == false)
- return null;
-
- KeyEntry entry = entries.get(alias);
- return (entry == null)
- ? null
- : entry.getPrivateKey();
- }
-
- /**
- * Returns the certificate chain associated with the given alias.
- *
- * @param alias the alias name
- *
- * @return the certificate chain (ordered with the user's certificate first
- * and the root certificate authority last), or null if the given alias
- * does not exist or does not contain a certificate chain (i.e., the given
- * alias identifies either a <i>trusted certificate entry</i> or a
- * <i>key entry</i> without a certificate chain).
- */
- public Certificate[] engineGetCertificateChain(String alias)
- {
- if (alias == null) {
- return null;
- }
-
- KeyEntry entry = entries.get(alias);
- X509Certificate[] certChain = (entry == null)
- ? null
- : entry.getCertificateChain();
- return (certChain == null)
- ? null
- : certChain.clone();
- }
-
- /**
- * Returns the certificate associated with the given alias.
- *
- * <p>If the given alias name identifies a
- * <i>trusted certificate entry</i>, the certificate associated with that
- * entry is returned. If the given alias name identifies a
- * <i>key entry</i>, the first element of the certificate chain of that
- * entry is returned, or null if that entry does not have a certificate
- * chain.
- *
- * @param alias the alias name
- *
- * @return the certificate, or null if the given alias does not exist or
- * does not contain a certificate.
- */
- public Certificate engineGetCertificate(String alias)
- {
- if (alias == null) {
- return null;
- }
-
- KeyEntry entry = entries.get(alias);
- X509Certificate[] certChain = (entry == null)
- ? null
- : entry.getCertificateChain();
- return (certChain == null || certChain.length == 0)
- ? null
- : certChain[0];
- }
-
- /**
- * Returns the creation date of the entry identified by the given alias.
- *
- * @param alias the alias name
- *
- * @return the creation date of this entry, or null if the given alias does
- * not exist
- */
- public Date engineGetCreationDate(String alias) {
- if (alias == null) {
- return null;
- }
- return new Date();
- }
-
- /**
- * Stores the given private key and associated certificate chain in the
- * keystore.
- *
- * <p>The given java.security.PrivateKey <code>key</code> must
- * be accompanied by a certificate chain certifying the
- * corresponding public key.
- *
- * <p>If the given alias already exists, the keystore information
- * associated with it is overridden by the given key and certificate
- * chain. Otherwise, a new entry is created.
- *
- * <p>
- * A compatibility mode is supported for applications that assume
- * a password must be supplied. It permits (but ignores) a non-null
- * <code>password</code>. The mode is enabled by default.
- * Set the
- * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
- * system property to <code>false</code> to disable compatibility mode
- * and reject a non-null <code>password</code>.
- *
- * @param alias the alias name
- * @param key the private key to be associated with the alias
- * @param password the password, which should be <code>null</code>
- * @param chain the certificate chain for the corresponding public
- * key (only required if the given key is of type
- * <code>java.security.PrivateKey</code>).
- *
- * @exception KeyStoreException if the given key is not a private key,
- * cannot be protected, or if compatibility mode is disabled and
- * <code>password</code> is non-null, or if this operation fails for
- * some other reason.
- */
- public void engineSetKeyEntry(String alias, java.security.Key key,
- char[] password, Certificate[] chain) throws KeyStoreException
- {
- if (alias == null) {
- throw new KeyStoreException("alias must not be null");
- }
-
- if (password != null && !keyStoreCompatibilityMode) {
- throw new KeyStoreException("Password must be null");
- }
-
- if (key instanceof RSAPrivateCrtKey) {
-
- KeyEntry entry = entries.get(alias);
-
- X509Certificate[] xchain;
- if (chain != null) {
- if (chain instanceof X509Certificate[]) {
- xchain = (X509Certificate[]) chain;
- } else {
- xchain = new X509Certificate[chain.length];
- System.arraycopy(chain, 0, xchain, 0, chain.length);
- }
- } else {
- xchain = null;
- }
-
- if (entry == null) {
- entry =
- //TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
- new KeyEntry(alias, null, xchain);
- storeWithUniqueAlias(alias, entry);
- }
-
- entry.setAlias(alias);
-
- try {
- entry.setPrivateKey((RSAPrivateCrtKey) key);
- entry.setCertificateChain(xchain);
-
- } catch (CertificateException ce) {
- throw new KeyStoreException(ce);
-
- } catch (InvalidKeyException ike) {
- throw new KeyStoreException(ike);
- }
-
- } else {
- throw new UnsupportedOperationException(
- "Cannot assign the key to the given alias.");
- }
- }
-
- /**
- * Assigns the given key (that has already been protected) to the given
- * alias.
- *
- * <p>If the protected key is of type
- * <code>java.security.PrivateKey</code>, it must be accompanied by a
- * certificate chain certifying the corresponding public key. If the
- * underlying keystore implementation is of type <code>jks</code>,
- * <code>key</code> must be encoded as an
- * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
- *
- * <p>If the given alias already exists, the keystore information
- * associated with it is overridden by the given key (and possibly
- * certificate chain).
- *
- * @param alias the alias name
- * @param key the key (in protected format) to be associated with the alias
- * @param chain the certificate chain for the corresponding public
- * key (only useful if the protected key is of type
- * <code>java.security.PrivateKey</code>).
- *
- * @exception KeyStoreException if this operation fails.
- */
- public void engineSetKeyEntry(String alias, byte[] key,
- Certificate[] chain)
- throws KeyStoreException
- {
- throw new UnsupportedOperationException(
- "Cannot assign the encoded key to the given alias.");
- }
-
- /**
- * Assigns the given certificate to the given alias.
- *
- * <p>If the given alias already exists in this keystore and identifies a
- * <i>trusted certificate entry</i>, the certificate associated with it is
- * overridden by the given certificate.
- *
- * @param alias the alias name
- * @param cert the certificate
- *
- * @exception KeyStoreException if the given alias already exists and does
- * not identify a <i>trusted certificate entry</i>, or this operation
- * fails for some other reason.
- */
- public void engineSetCertificateEntry(String alias, Certificate cert)
- throws KeyStoreException
- {
- if (alias == null) {
- throw new KeyStoreException("alias must not be null");
- }
-
- if (cert instanceof X509Certificate) {
-
- // TODO - build CryptoAPI chain?
- X509Certificate[] chain =
- new X509Certificate[]{ (X509Certificate) cert };
- KeyEntry entry = entries.get(alias);
-
- if (entry == null) {
- entry =
- new KeyEntry(alias, null, chain);
- storeWithUniqueAlias(alias, entry);
- }
-
- if (entry.getPrivateKey() == null) { // trusted-cert entry
- entry.setAlias(alias);
-
- try {
- entry.setCertificateChain(chain);
-
- } catch (CertificateException ce) {
- throw new KeyStoreException(ce);
- }
- }
-
- } else {
- throw new UnsupportedOperationException(
- "Cannot assign the certificate to the given alias.");
- }
- }
-
- /**
- * Deletes the entry identified by the given alias from this keystore.
- *
- * @param alias the alias name
- *
- * @exception KeyStoreException if the entry cannot be removed.
- */
- public void engineDeleteEntry(String alias)
- throws KeyStoreException
- {
- if (alias == null) {
- throw new KeyStoreException("alias must not be null");
- }
-
- KeyEntry entry = entries.remove(alias);
- if (entry != null) {
- // Get end-entity certificate and remove from system cert store
- X509Certificate[] certChain = entry.getCertificateChain();
- if (certChain != null && certChain.length > 0) {
-
- try {
-
- byte[] encoding = certChain[0].getEncoded();
- removeCertificate(getName(), entry.getAlias(), encoding,
- encoding.length);
-
- } catch (CertificateException e) {
- throw new KeyStoreException("Cannot remove entry: ", e);
- }
- }
- Key privateKey = entry.getPrivateKey();
- if (privateKey != null) {
- destroyKeyContainer(
- Key.getContainerName(privateKey.getHCryptProvider()));
- }
- }
- }
-
- /**
- * Lists all the alias names of this keystore.
- *
- * @return enumeration of the alias names
- */
- public Enumeration<String> engineAliases() {
- final Iterator<String> iter = entries.keySet().iterator();
-
- return new Enumeration<String>()
- {
- public boolean hasMoreElements()
- {
- return iter.hasNext();
- }
-
- public String nextElement()
- {
- return iter.next();
- }
- };
- }
-
- /**
- * Checks if the given alias exists in this keystore.
- *
- * @param alias the alias name
- *
- * @return true if the alias exists, false otherwise
- */
- public boolean engineContainsAlias(String alias) {
- return entries.containsKey(alias);
- }
-
- /**
- * Retrieves the number of entries in this keystore.
- *
- * @return the number of entries in this keystore
- */
- public int engineSize() {
- return entries.size();
- }
-
- /**
- * Returns true if the entry identified by the given alias is a
- * <i>key entry</i>, and false otherwise.
- *
- * @return true if the entry identified by the given alias is a
- * <i>key entry</i>, false otherwise.
- */
- public boolean engineIsKeyEntry(String alias) {
-
- if (alias == null) {
- return false;
- }
-
- KeyEntry entry = entries.get(alias);
- return entry != null && entry.getPrivateKey() != null;
- }
-
- /**
- * Returns true if the entry identified by the given alias is a
- * <i>trusted certificate entry</i>, and false otherwise.
- *
- * @return true if the entry identified by the given alias is a
- * <i>trusted certificate entry</i>, false otherwise.
- */
- public boolean engineIsCertificateEntry(String alias) {
-
- if (alias == null) {
- return false;
- }
-
- KeyEntry entry = entries.get(alias);
- return entry != null && entry.getPrivateKey() == null;
- }
-
- /**
- * Returns the (alias) name of the first keystore entry whose certificate
- * matches the given certificate.
- *
- * <p>This method attempts to match the given certificate with each
- * keystore entry. If the entry being considered
- * is a <i>trusted certificate entry</i>, the given certificate is
- * compared to that entry's certificate. If the entry being considered is
- * a <i>key entry</i>, the given certificate is compared to the first
- * element of that entry's certificate chain (if a chain exists).
- *
- * @param cert the certificate to match with.
- *
- * @return the (alias) name of the first entry with matching certificate,
- * or null if no such entry exists in this keystore.
- */
- public String engineGetCertificateAlias(Certificate cert) {
-
- for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) {
- KeyEntry entry = mapEntry.getValue();
- if (entry.certChain != null &&
- entry.certChain.length > 0 &&
- entry.certChain[0].equals(cert)) {
- return entry.getAlias();
- }
- }
-
- return null;
- }
-
- /**
- * engineStore is currently a no-op.
- * Entries are stored during engineSetEntry.
- *
- * A compatibility mode is supported for applications that assume
- * keystores are stream-based. It permits (but ignores) a non-null
- * <code>stream</code> or <code>password</code>.
- * The mode is enabled by default.
- * Set the
- * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
- * system property to <code>false</code> to disable compatibility mode
- * and reject a non-null <code>stream</code> or <code>password</code>.
- *
- * @param stream the output stream, which should be <code>null</code>
- * @param password the password, which should be <code>null</code>
- *
- * @exception IOException if compatibility mode is disabled and either
- * parameter is non-null.
- */
- public void engineStore(OutputStream stream, char[] password)
- throws IOException, NoSuchAlgorithmException, CertificateException
- {
- if (stream != null && !keyStoreCompatibilityMode) {
- throw new IOException("Keystore output stream must be null");
- }
-
- if (password != null && !keyStoreCompatibilityMode) {
- throw new IOException("Keystore password must be null");
- }
- }
-
- /**
- * Loads the keystore.
- *
- * A compatibility mode is supported for applications that assume
- * keystores are stream-based. It permits (but ignores) a non-null
- * <code>stream</code> or <code>password</code>.
- * The mode is enabled by default.
- * Set the
- * <code>sun.security.mscapi.keyStoreCompatibilityMode</code>
- * system property to <code>false</code> to disable compatibility mode
- * and reject a non-null <code>stream</code> or <code>password</code>.
- *
- * @param stream the input stream, which should be <code>null</code>.
- * @param password the password, which should be <code>null</code>.
- *
- * @exception IOException if there is an I/O or format problem with the
- * keystore data. Or if compatibility mode is disabled and either
- * parameter is non-null.
- * @exception NoSuchAlgorithmException if the algorithm used to check
- * the integrity of the keystore cannot be found
- * @exception CertificateException if any of the certificates in the
- * keystore could not be loaded
- * @exception SecurityException if the security check for
- * <code>SecurityPermission("authProvider.<i>name</i>")</code> does not
- * pass, where <i>name</i> is the value returned by
- * this provider's <code>getName</code> method.
- */
- public void engineLoad(InputStream stream, char[] password)
- throws IOException, NoSuchAlgorithmException, CertificateException
- {
- if (stream != null && !keyStoreCompatibilityMode) {
- throw new IOException("Keystore input stream must be null");
- }
-
- if (password != null && !keyStoreCompatibilityMode) {
- throw new IOException("Keystore password must be null");
- }
-
- /*
- * Use the same security check as AuthProvider.login
- */
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new SecurityPermission(
- "authProvider.SunMSCAPI"));
- }
-
- // Clear all key entries
- entries.clear();
-
- try {
-
- // Load keys and/or certificate chains
- loadKeysOrCertificateChains(getName());
-
- } catch (KeyStoreException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Stores the given entry into the map, making sure
- * the alias, used as the key is unique.
- * If the same alias already exists, it tries to append
- * a suffix (1), (2), etc to it until it finds a unique
- * value.
- */
- private void storeWithUniqueAlias(String alias, KeyEntry entry) {
- String uniqAlias = alias;
- int uniqNum = 1;
-
- while (true) {
- if (entries.putIfAbsent(uniqAlias, entry) == null) {
- break;
- }
- uniqAlias = alias + " (" + (uniqNum++) + ")";
- }
- }
-
-
- /**
- * Generates a certificate chain from the collection of
- * certificates and stores the result into a key entry.
- */
- private void generateCertificateChain(String alias,
- Collection<? extends Certificate> certCollection)
- {
- try
- {
- X509Certificate[] certChain =
- new X509Certificate[certCollection.size()];
-
- int i = 0;
- for (Iterator<? extends Certificate> iter =
- certCollection.iterator(); iter.hasNext(); i++)
- {
- certChain[i] = (X509Certificate) iter.next();
- }
-
- storeWithUniqueAlias(alias,
- new KeyEntry(alias, null, certChain));
- }
- catch (Throwable e)
- {
- // Ignore the exception and skip this entry
- // TODO - throw CertificateException?
- }
- }
-
- /**
- * Generates RSA key and certificate chain from the private key handle,
- * collection of certificates and stores the result into key entries.
- */
- private void generateRSAKeyAndCertificateChain(String alias,
- long hCryptProv, long hCryptKey, int keyLength,
- Collection<? extends Certificate> certCollection)
- {
- try
- {
- X509Certificate[] certChain =
- new X509Certificate[certCollection.size()];
-
- int i = 0;
- for (Iterator<? extends Certificate> iter =
- certCollection.iterator(); iter.hasNext(); i++)
- {
- certChain[i] = (X509Certificate) iter.next();
- }
-
- storeWithUniqueAlias(alias, new KeyEntry(alias,
- new RSAPrivateKey(new Key.NativeHandles(hCryptProv,
- hCryptKey), keyLength),
- certChain));
- }
- catch (Throwable e)
- {
- // Ignore the exception and skip this entry
- // TODO - throw CertificateException?
- }
- }
-
- /**
- * Generates certificates from byte data and stores into cert collection.
- *
- * @param data Byte data.
- * @param certCollection Collection of certificates.
- */
- private void generateCertificate(byte[] data,
- Collection<Certificate> certCollection) {
- try
- {
- ByteArrayInputStream bis = new ByteArrayInputStream(data);
-
- // Obtain certificate factory
- if (certificateFactory == null) {
- certificateFactory = CertificateFactory.getInstance("X.509", "SUN");
- }
-
- // Generate certificate
- Collection<? extends Certificate> c =
- certificateFactory.generateCertificates(bis);
- certCollection.addAll(c);
- }
- catch (CertificateException e)
- {
- // Ignore the exception and skip this certificate
- // TODO - throw CertificateException?
- }
- catch (Throwable te)
- {
- // Ignore the exception and skip this certificate
- // TODO - throw CertificateException?
- }
- }
-
- /**
- * Returns the name of the keystore.
- */
- private String getName()
- {
- return storeName;
- }
-
- /**
- * Load keys and/or certificates from keystore into Collection.
- *
- * @param name Name of keystore.
- */
- private native void loadKeysOrCertificateChains(String name)
- throws KeyStoreException;
-
- /**
- * Stores a DER-encoded certificate into the certificate store
- *
- * @param name Name of the keystore.
- * @param alias Name of the certificate.
- * @param encoding DER-encoded certificate.
- */
- private native void storeCertificate(String name, String alias,
- byte[] encoding, int encodingLength, long hCryptProvider,
- long hCryptKey) throws CertificateException, KeyStoreException;
-
- /**
- * Removes the certificate from the certificate store
- *
- * @param name Name of the keystore.
- * @param alias Name of the certificate.
- * @param encoding DER-encoded certificate.
- */
- private native void removeCertificate(String name, String alias,
- byte[] encoding, int encodingLength)
- throws CertificateException, KeyStoreException;
-
- /**
- * Destroys the key container.
- *
- * @param keyContainerName The name of the key container.
- */
- private native void destroyKeyContainer(String keyContainerName)
- throws KeyStoreException;
-
- /**
- * Generates a private-key BLOB from a key's components.
- */
- private native byte[] generatePrivateKeyBlob(
- int keyBitLength,
- byte[] modulus,
- byte[] publicExponent,
- byte[] privateExponent,
- byte[] primeP,
- byte[] primeQ,
- byte[] exponentP,
- byte[] exponentQ,
- byte[] crtCoefficient) throws InvalidKeyException;
-
- private native RSAPrivateKey storePrivateKey(byte[] keyBlob,
- String keyContainerName, int keySize) throws KeyStoreException;
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/PRNG.java Thu Dec 13 09:02:52 2018 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/PRNG.java Thu Dec 13 17:28:19 2018 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSACipher.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,501 +0,0 @@
-/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.math.BigInteger;
-import java.security.*;
-import java.security.Key;
-import java.security.interfaces.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import sun.security.rsa.RSAKeyFactory;
-import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
-import sun.security.util.KeyUtil;
-
-/**
- * RSA cipher implementation using the Microsoft Crypto API.
- * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
- *
- * Objects should be instantiated by calling Cipher.getInstance() using the
- * following algorithm name:
- *
- * . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype)
- * is selected based on the en/decryption mode and public/private key used.
- *
- * We only do one RSA operation per doFinal() call. If the application passes
- * more data via calls to update() or doFinal(), we throw an
- * IllegalBlockSizeException when doFinal() is called (see JCE API spec).
- * Bulk encryption using RSA does not make sense and is not standardized.
- *
- * Note: RSA keys should be at least 512 bits long
- *
- * @since 1.6
- * @author Andreas Sterbenz
- * @author Vincent Ryan
- */
-public final class RSACipher extends CipherSpi {
-
- // constant for an empty byte array
- private final static byte[] B0 = new byte[0];
-
- // mode constant for public key encryption
- private final static int MODE_ENCRYPT = 1;
- // mode constant for private key decryption
- private final static int MODE_DECRYPT = 2;
- // mode constant for private key encryption (signing)
- private final static int MODE_SIGN = 3;
- // mode constant for public key decryption (verifying)
- private final static int MODE_VERIFY = 4;
-
- // constant for PKCS#1 v1.5 RSA
- private final static String PAD_PKCS1 = "PKCS1Padding";
- private final static int PAD_PKCS1_LENGTH = 11;
-
- // current mode, one of MODE_* above. Set when init() is called
- private int mode;
-
- // active padding type, one of PAD_* above. Set by setPadding()
- private String paddingType;
- private int paddingLength = 0;
-
- // buffer for the data
- private byte[] buffer;
- // offset into the buffer (number of bytes buffered)
- private int bufOfs;
-
- // size of the output (the length of the key).
- private int outputSize;
-
- // the public key, if we were initialized using a public key
- private sun.security.mscapi.Key publicKey;
-
- // the private key, if we were initialized using a private key
- private sun.security.mscapi.Key privateKey;
-
- // cipher parameter for TLS RSA premaster secret
- private AlgorithmParameterSpec spec = null;
-
- // the source of randomness
- private SecureRandom random;
-
- public RSACipher() {
- paddingType = PAD_PKCS1;
- }
-
- // modes do not make sense for RSA, but allow ECB
- // see JCE spec
- protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
- if (mode.equalsIgnoreCase("ECB") == false) {
- throw new NoSuchAlgorithmException("Unsupported mode " + mode);
- }
- }
-
- // set the padding type
- // see JCE spec
- protected void engineSetPadding(String paddingName)
- throws NoSuchPaddingException {
- if (paddingName.equalsIgnoreCase(PAD_PKCS1)) {
- paddingType = PAD_PKCS1;
- } else {
- throw new NoSuchPaddingException
- ("Padding " + paddingName + " not supported");
- }
- }
-
- // return 0 as block size, we are not a block cipher
- // see JCE spec
- protected int engineGetBlockSize() {
- return 0;
- }
-
- // return the output size
- // see JCE spec
- protected int engineGetOutputSize(int inputLen) {
- return outputSize;
- }
-
- // no iv, return null
- // see JCE spec
- protected byte[] engineGetIV() {
- return null;
- }
-
- // no parameters, return null
- // see JCE spec
- protected AlgorithmParameters engineGetParameters() {
- return null;
- }
-
- // see JCE spec
- protected void engineInit(int opmode, Key key, SecureRandom random)
- throws InvalidKeyException {
- init(opmode, key);
- }
-
- // see JCE spec
- @SuppressWarnings("deprecation")
- protected void engineInit(int opmode, Key key,
- AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
-
- if (params != null) {
- if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
- throw new InvalidAlgorithmParameterException(
- "Parameters not supported");
- }
- spec = params;
- this.random = random; // for TLS RSA premaster secret
- }
- init(opmode, key);
- }
-
- // see JCE spec
- protected void engineInit(int opmode, Key key,
- AlgorithmParameters params, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
-
- if (params != null) {
- throw new InvalidAlgorithmParameterException
- ("Parameters not supported");
- }
- init(opmode, key);
- }
-
- // initialize this cipher
- private void init(int opmode, Key key) throws InvalidKeyException {
-
- boolean encrypt;
-
- switch (opmode) {
- case Cipher.ENCRYPT_MODE:
- case Cipher.WRAP_MODE:
- paddingLength = PAD_PKCS1_LENGTH;
- encrypt = true;
- break;
- case Cipher.DECRYPT_MODE:
- case Cipher.UNWRAP_MODE:
- paddingLength = 0; // reset
- encrypt = false;
- break;
- default:
- throw new InvalidKeyException("Unknown mode: " + opmode);
- }
-
- if (!(key instanceof sun.security.mscapi.Key)) {
- if (key instanceof java.security.interfaces.RSAPublicKey) {
- java.security.interfaces.RSAPublicKey rsaKey =
- (java.security.interfaces.RSAPublicKey) key;
-
- // Convert key to MSCAPI format
-
- BigInteger modulus = rsaKey.getModulus();
- BigInteger exponent = rsaKey.getPublicExponent();
-
- // Check against the local and global values to make sure
- // the sizes are ok. Round up to the nearest byte.
- RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
- exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
-
- byte[] modulusBytes = modulus.toByteArray();
- byte[] exponentBytes = exponent.toByteArray();
-
- // Adjust key length due to sign bit
- int keyBitLength = (modulusBytes[0] == 0)
- ? (modulusBytes.length - 1) * 8
- : modulusBytes.length * 8;
-
- byte[] keyBlob = RSASignature.generatePublicKeyBlob(
- keyBitLength, modulusBytes, exponentBytes);
-
- try {
- key = RSASignature.importPublicKey(keyBlob, keyBitLength);
-
- } catch (KeyStoreException e) {
- throw new InvalidKeyException(e);
- }
-
- } else {
- throw new InvalidKeyException("Unsupported key type: " + key);
- }
- }
-
- if (key instanceof PublicKey) {
- mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
- publicKey = (sun.security.mscapi.Key)key;
- privateKey = null;
- outputSize = publicKey.length() / 8;
- } else if (key instanceof PrivateKey) {
- mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
- privateKey = (sun.security.mscapi.Key)key;
- publicKey = null;
- outputSize = privateKey.length() / 8;
- } else {
- throw new InvalidKeyException("Unknown key type: " + key);
- }
-
- bufOfs = 0;
- buffer = new byte[outputSize];
- }
-
- // internal update method
- private void update(byte[] in, int inOfs, int inLen) {
- if ((inLen == 0) || (in == null)) {
- return;
- }
- if (bufOfs + inLen > (buffer.length - paddingLength)) {
- bufOfs = buffer.length + 1;
- return;
- }
- System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
- bufOfs += inLen;
- }
-
- // internal doFinal() method. Here we perform the actual RSA operation
- private byte[] doFinal() throws BadPaddingException,
- IllegalBlockSizeException {
- if (bufOfs > buffer.length) {
- throw new IllegalBlockSizeException("Data must not be longer "
- + "than " + (buffer.length - paddingLength) + " bytes");
- }
-
- try {
- byte[] data = buffer;
- switch (mode) {
- case MODE_SIGN:
- return encryptDecrypt(data, bufOfs,
- privateKey.getHCryptKey(), true);
-
- case MODE_VERIFY:
- return encryptDecrypt(data, bufOfs,
- publicKey.getHCryptKey(), false);
-
- case MODE_ENCRYPT:
- return encryptDecrypt(data, bufOfs,
- publicKey.getHCryptKey(), true);
-
- case MODE_DECRYPT:
- return encryptDecrypt(data, bufOfs,
- privateKey.getHCryptKey(), false);
-
- default:
- throw new AssertionError("Internal error");
- }
-
- } catch (KeyException e) {
- throw new ProviderException(e);
-
- } finally {
- bufOfs = 0;
- }
- }
-
- // see JCE spec
- protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
- update(in, inOfs, inLen);
- return B0;
- }
-
- // see JCE spec
- protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
- int outOfs) {
- update(in, inOfs, inLen);
- return 0;
- }
-
- // see JCE spec
- protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
- throws BadPaddingException, IllegalBlockSizeException {
- update(in, inOfs, inLen);
- return doFinal();
- }
-
- // see JCE spec
- protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
- int outOfs) throws ShortBufferException, BadPaddingException,
- IllegalBlockSizeException {
- if (outputSize > out.length - outOfs) {
- throw new ShortBufferException
- ("Need " + outputSize + " bytes for output");
- }
- update(in, inOfs, inLen);
- byte[] result = doFinal();
- int n = result.length;
- System.arraycopy(result, 0, out, outOfs, n);
- return n;
- }
-
- // see JCE spec
- protected byte[] engineWrap(Key key) throws InvalidKeyException,
- IllegalBlockSizeException {
- byte[] encoded = key.getEncoded(); // TODO - unextractable key
- if ((encoded == null) || (encoded.length == 0)) {
- throw new InvalidKeyException("Could not obtain encoded key");
- }
- if (encoded.length > buffer.length) {
- throw new InvalidKeyException("Key is too long for wrapping");
- }
- update(encoded, 0, encoded.length);
- try {
- return doFinal();
- } catch (BadPaddingException e) {
- // should not occur
- throw new InvalidKeyException("Wrapping failed", e);
- }
- }
-
- // see JCE spec
- @SuppressWarnings("deprecation")
- protected java.security.Key engineUnwrap(byte[] wrappedKey,
- String algorithm,
- int type) throws InvalidKeyException, NoSuchAlgorithmException {
-
- if (wrappedKey.length > buffer.length) {
- throw new InvalidKeyException("Key is too long for unwrapping");
- }
-
- boolean isTlsRsaPremasterSecret =
- algorithm.equals("TlsRsaPremasterSecret");
- Exception failover = null;
- byte[] encoded = null;
-
- update(wrappedKey, 0, wrappedKey.length);
- try {
- encoded = doFinal();
- } catch (BadPaddingException e) {
- if (isTlsRsaPremasterSecret) {
- failover = e;
- } else {
- throw new InvalidKeyException("Unwrapping failed", e);
- }
- } catch (IllegalBlockSizeException e) {
- // should not occur, handled with length check above
- throw new InvalidKeyException("Unwrapping failed", e);
- }
-
- if (isTlsRsaPremasterSecret) {
- if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
- throw new IllegalStateException(
- "No TlsRsaPremasterSecretParameterSpec specified");
- }
-
- // polish the TLS premaster secret
- encoded = KeyUtil.checkTlsPreMasterSecretKey(
- ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
- ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
- random, encoded, (failover != null));
- }
-
- return constructKey(encoded, algorithm, type);
- }
-
- // see JCE spec
- protected int engineGetKeySize(Key key) throws InvalidKeyException {
-
- if (key instanceof sun.security.mscapi.Key) {
- return ((sun.security.mscapi.Key) key).length();
-
- } else if (key instanceof RSAKey) {
- return ((RSAKey) key).getModulus().bitLength();
-
- } else {
- throw new InvalidKeyException("Unsupported key type: " + key);
- }
- }
-
- // Construct an X.509 encoded public key.
- private static PublicKey constructPublicKey(byte[] encodedKey,
- String encodedKeyAlgorithm)
- throws InvalidKeyException, NoSuchAlgorithmException {
-
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
- X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
-
- return keyFactory.generatePublic(keySpec);
-
- } catch (NoSuchAlgorithmException nsae) {
- throw new NoSuchAlgorithmException("No installed provider " +
- "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
-
- } catch (InvalidKeySpecException ike) {
- throw new InvalidKeyException("Cannot construct public key", ike);
- }
- }
-
- // Construct a PKCS #8 encoded private key.
- private static PrivateKey constructPrivateKey(byte[] encodedKey,
- String encodedKeyAlgorithm)
- throws InvalidKeyException, NoSuchAlgorithmException {
-
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
-
- return keyFactory.generatePrivate(keySpec);
-
- } catch (NoSuchAlgorithmException nsae) {
- throw new NoSuchAlgorithmException("No installed provider " +
- "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
-
- } catch (InvalidKeySpecException ike) {
- throw new InvalidKeyException("Cannot construct private key", ike);
- }
- }
-
- // Construct an encoded secret key.
- private static SecretKey constructSecretKey(byte[] encodedKey,
- String encodedKeyAlgorithm) {
-
- return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
- }
-
- private static Key constructKey(byte[] encodedKey,
- String encodedKeyAlgorithm,
- int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
-
- switch (keyType) {
- case Cipher.PUBLIC_KEY:
- return constructPublicKey(encodedKey, encodedKeyAlgorithm);
- case Cipher.PRIVATE_KEY:
- return constructPrivateKey(encodedKey, encodedKeyAlgorithm);
- case Cipher.SECRET_KEY:
- return constructSecretKey(encodedKey, encodedKeyAlgorithm);
- default:
- throw new InvalidKeyException("Unknown key type " + keyType);
- }
- }
-
- /*
- * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY.
- * It expects and returns ciphertext data in big-endian form.
- */
- private native static byte[] encryptDecrypt(byte[] data, int dataSize,
- long hCryptKey, boolean doEncrypt) throws KeyException;
-
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-/**
- * The handle for an RSA public/private keypair using the Microsoft Crypto API.
- *
- * @since 1.6
- */
-class RSAKeyPair {
-
- private final RSAPrivateKey privateKey;
-
- private final RSAPublicKey publicKey;
-
- /**
- * Construct an RSAKeyPair object.
- */
- RSAKeyPair(long hCryptProv, long hCryptKey, int keyLength)
- {
- Key.NativeHandles handles = new Key.NativeHandles(hCryptProv, hCryptKey);
- privateKey = new RSAPrivateKey(handles, keyLength);
- publicKey = new RSAPublicKey(handles, keyLength);
- }
-
- public RSAPrivateKey getPrivate() {
- return privateKey;
- }
-
- public RSAPublicKey getPublic() {
- return publicKey;
- }
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.util.UUID;
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-
-import sun.security.rsa.RSAKeyFactory;
-import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
-
-/**
- * RSA keypair generator.
- *
- * Standard algorithm, minimum key length is 512 bit, maximum is 16,384.
- * Generates a private key that is exportable.
- *
- * @since 1.6
- */
-public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
-
- // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
- static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
- static final int KEY_SIZE_MAX = 16384;
-
- // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
- private int keySize;
-
- public RSAKeyPairGenerator() {
- // initialize to default in case the app does not call initialize()
- initialize(DEF_RSA_KEY_SIZE, null);
- }
-
- // initialize the generator. See JCA doc
- // random is always ignored
- public void initialize(int keySize, SecureRandom random) {
-
- try {
- RSAKeyFactory.checkKeyLengths(keySize, null,
- KEY_SIZE_MIN, KEY_SIZE_MAX);
- } catch (InvalidKeyException e) {
- throw new InvalidParameterException(e.getMessage());
- }
-
- this.keySize = keySize;
- }
-
- // second initialize method. See JCA doc
- // random and exponent are always ignored
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
-
- int tmpSize;
- if (params == null) {
- tmpSize = DEF_RSA_KEY_SIZE;
- } else if (params instanceof RSAKeyGenParameterSpec) {
-
- if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
- throw new InvalidAlgorithmParameterException
- ("Exponent parameter is not supported");
- }
- tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
-
- } else {
- throw new InvalidAlgorithmParameterException
- ("Params must be an instance of RSAKeyGenParameterSpec");
- }
-
- try {
- RSAKeyFactory.checkKeyLengths(tmpSize, null,
- KEY_SIZE_MIN, KEY_SIZE_MAX);
- } catch (InvalidKeyException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid Key sizes", e);
- }
-
- this.keySize = tmpSize;
- }
-
- // generate the keypair. See JCA doc
- public KeyPair generateKeyPair() {
-
- try {
-
- // Generate each keypair in a unique key container
- RSAKeyPair keys =
- generateRSAKeyPair(keySize,
- "{" + UUID.randomUUID().toString() + "}");
-
- return new KeyPair(keys.getPublic(), keys.getPrivate());
-
- } catch (KeyException e) {
- throw new ProviderException(e);
- }
- }
-
- private static native RSAKeyPair generateRSAKeyPair(int keySize,
- String keyContainerName) throws KeyException;
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.security.PrivateKey;
-
-/**
- * The handle for an RSA private key using the Microsoft Crypto API.
- *
- * @author Stanley Man-Kit Ho
- * @since 1.6
- */
-class RSAPrivateKey extends Key implements PrivateKey
-{
- private static final long serialVersionUID = 8113152807912338063L;
-
- /**
- * Construct an RSAPrivateKey object.
- */
- RSAPrivateKey(long hCryptProv, long hCryptKey, int keyLength)
- {
- super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
- }
-
- /**
- * Construct an RSAPrivateKey object.
- */
- RSAPrivateKey(NativeHandles handles, int keyLength)
- {
- super(handles, keyLength);
- }
-
- /**
- * Returns the standard algorithm name for this key. For
- * example, "RSA" would indicate that this key is a RSA key.
- * See Appendix A in the <a href=
- * "../../../guide/security/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for information about standard algorithm names.
- *
- * @return the name of the algorithm associated with this key.
- */
- public String getAlgorithm()
- {
- return "RSA";
- }
-
- public String toString()
- {
- return "RSAPrivateKey [size=" + keyLength + " bits, type=" +
- getKeyType(handles.hCryptKey) + ", container=" +
- getContainerName(handles.hCryptProv) + "]";
- }
-
- // This class is not serializable
- private void writeObject(java.io.ObjectOutputStream out)
- throws java.io.IOException {
-
- throw new java.io.NotSerializableException();
- }
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.math.BigInteger;
-import java.security.KeyException;
-import java.security.KeyRep;
-import java.security.ProviderException;
-
-import sun.security.rsa.RSAUtil.KeyType;
-import sun.security.rsa.RSAPublicKeyImpl;
-
-/**
- * The handle for an RSA public key using the Microsoft Crypto API.
- *
- * @since 1.6
- */
-class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey
-{
- private static final long serialVersionUID = -2289561342425825391L;
-
- private byte[] publicKeyBlob = null;
- private byte[] encoding = null;
- private BigInteger modulus = null;
- private BigInteger exponent = null;
-
- /**
- * Construct an RSAPublicKey object.
- */
- RSAPublicKey(long hCryptProv, long hCryptKey, int keyLength)
- {
- super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
- }
-
- /**
- * Construct an RSAPublicKey object.
- */
- RSAPublicKey(NativeHandles handles, int keyLength)
- {
- super(handles, keyLength);
- }
-
- /**
- * Returns the standard algorithm name for this key. For
- * example, "RSA" would indicate that this key is a RSA key.
- * See Appendix A in the <a href=
- * "../../../guide/security/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification & Reference </a>
- * for information about standard algorithm names.
- *
- * @return the name of the algorithm associated with this key.
- */
- public String getAlgorithm()
- {
- return "RSA";
- }
-
- /**
- * Returns a printable description of the key.
- */
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
-
- sb.append("RSAPublicKey [size=").append(keyLength)
- .append(" bits, type=").append(getKeyType(handles.hCryptKey))
- .append(", container=").append(getContainerName(handles.hCryptProv))
- .append("]\n modulus: ").append(getModulus())
- .append("\n public exponent: ").append(getPublicExponent());
-
- return sb.toString();
- }
-
- /**
- * Returns the public exponent.
- */
- public BigInteger getPublicExponent() {
-
- if (exponent == null) {
-
- try {
- publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
- exponent = new BigInteger(1, getExponent(publicKeyBlob));
-
- } catch (KeyException e) {
- throw new ProviderException(e);
- }
- }
-
- return exponent;
- }
-
- /**
- * Returns the modulus.
- */
- public BigInteger getModulus() {
-
- if (modulus == null) {
-
- try {
- publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
- modulus = new BigInteger(1, getModulus(publicKeyBlob));
-
- } catch (KeyException e) {
- throw new ProviderException(e);
- }
- }
-
- return modulus;
- }
-
- /**
- * Returns the name of the primary encoding format of this key,
- * or null if this key does not support encoding.
- * The primary encoding format is
- * named in terms of the appropriate ASN.1 data format, if an
- * ASN.1 specification for this key exists.
- * For example, the name of the ASN.1 data format for public
- * keys is <I>SubjectPublicKeyInfo</I>, as
- * defined by the X.509 standard; in this case, the returned format is
- * <code>"X.509"</code>. Similarly,
- * the name of the ASN.1 data format for private keys is
- * <I>PrivateKeyInfo</I>,
- * as defined by the PKCS #8 standard; in this case, the returned format is
- * <code>"PKCS#8"</code>.
- *
- * @return the primary encoding format of the key.
- */
- public String getFormat()
- {
- return "X.509";
- }
-
- /**
- * Returns the key in its primary encoding format, or null
- * if this key does not support encoding.
- *
- * @return the encoded key, or null if the key does not support
- * encoding.
- */
- public byte[] getEncoded()
- {
- if (encoding == null) {
-
- try {
- encoding = RSAPublicKeyImpl.newKey(KeyType.RSA, null,
- getModulus(), getPublicExponent()).getEncoded();
-
- } catch (KeyException e) {
- // ignore
- }
- }
- return encoding;
- }
-
- protected Object writeReplace() throws java.io.ObjectStreamException {
- return new KeyRep(KeyRep.Type.PUBLIC,
- getAlgorithm(),
- getFormat(),
- getEncoded());
- }
-
- /*
- * Returns the Microsoft CryptoAPI representation of the key.
- */
- private native byte[] getPublicKeyBlob(long hCryptKey) throws KeyException;
-
- /*
- * Returns the key's public exponent (in big-endian 2's complement format).
- */
- private native byte[] getExponent(byte[] keyBlob) throws KeyException;
-
- /*
- * Returns the key's modulus (in big-endian 2's complement format).
- */
- private native byte[] getModulus(byte[] keyBlob) throws KeyException;
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSASignature.java Thu Dec 13 09:02:52 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,805 +0,0 @@
-/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.mscapi;
-
-import java.nio.ByteBuffer;
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-import java.math.BigInteger;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
-import java.util.Locale;
-
-import sun.security.rsa.RSAKeyFactory;
-
-/**
- * RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding.
- *
- * Objects should be instantiated by calling Signature.getInstance() using the
- * following algorithm names:
- *
- * . "NONEwithRSA"
- * . "SHA1withRSA"
- * . "SHA256withRSA"
- * . "SHA384withRSA"
- * . "SHA512withRSA"
- * . "MD5withRSA"
- * . "MD2withRSA"
- * . "RSASSA-PSS"
- *
- * NOTE: RSA keys must be at least 512 bits long.
- *
- * NOTE: NONEwithRSA must be supplied with a pre-computed message digest.
- * Only the following digest algorithms are supported: MD5, SHA-1,
- * SHA-256, SHA-384, SHA-512 and a special-purpose digest
- * algorithm which is a concatenation of SHA-1 and MD5 digests.
- *
- * @since 1.6
- * @author Stanley Man-Kit Ho
- */
-abstract class RSASignature extends java.security.SignatureSpi
-{
- // message digest implementation we use
- protected MessageDigest messageDigest;
-
- // message digest name
- private String messageDigestAlgorithm;
-
- // flag indicating whether the digest has been reset
- protected boolean needsReset;
-
- // the signing key
- protected Key privateKey = null;
-
- // the verification key
- protected Key publicKey = null;
-
- /**
- * Constructs a new RSASignature. Used by Raw subclass.
- */
- RSASignature() {
- messageDigest = null;
- messageDigestAlgorithm = null;
- }
-
- /**
- * Constructs a new RSASignature. Used by subclasses.
- */
- RSASignature(String digestName) {
-
- try {
- messageDigest = MessageDigest.getInstance(digestName);
- // Get the digest's canonical name
- messageDigestAlgorithm = messageDigest.getAlgorithm();
-
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(e);
- }
-
- needsReset = false;
- }
-
- // Nested class for NONEwithRSA signatures
- public static final class Raw extends RSASignature {
-
- // the longest supported digest is 512 bits (SHA-512)
- private static final int RAW_RSA_MAX = 64;
-
- private final byte[] precomputedDigest;
- private int offset = 0;
-
- public Raw() {
- precomputedDigest = new byte[RAW_RSA_MAX];
- }
-
- // Stores the precomputed message digest value.
- @Override
- protected void engineUpdate(byte b) throws SignatureException {
- if (offset >= precomputedDigest.length) {
- offset = RAW_RSA_MAX + 1;
- return;
- }
- precomputedDigest[offset++] = b;
- }
-
- // Stores the precomputed message digest value.
- @Override
- protected void engineUpdate(byte[] b, int off, int len)
- throws SignatureException {
- if (len > (precomputedDigest.length - offset)) {
- offset = RAW_RSA_MAX + 1;
- return;
- }
- System.arraycopy(b, off, precomputedDigest, offset, len);
- offset += len;
- }
-
- // Stores the precomputed message digest value.
- @Override
- protected void engineUpdate(ByteBuffer byteBuffer) {
- int len = byteBuffer.remaining();
- if (len <= 0) {
- return;
- }
- if (len > (precomputedDigest.length - offset)) {
- offset = RAW_RSA_MAX + 1;
- return;
- }
- byteBuffer.get(precomputedDigest, offset, len);
- offset += len;
- }
-
- @Override
- protected void resetDigest(){
- offset = 0;
- }
-
- // Returns the precomputed message digest value.
- @Override
- protected byte[] getDigestValue() throws SignatureException {
- if (offset > RAW_RSA_MAX) {
- throw new SignatureException("Message digest is too long");
- }
-
- // Determine the digest algorithm from the digest length
- if (offset == 20) {
- setDigestName("SHA1");
- } else if (offset == 36) {
- setDigestName("SHA1+MD5");
- } else if (offset == 32) {
- setDigestName("SHA-256");
- } else if (offset == 48) {
- setDigestName("SHA-384");
- } else if (offset == 64) {
- setDigestName("SHA-512");
- } else if (offset == 16) {
- setDigestName("MD5");
- } else {
- throw new SignatureException(
- "Message digest length is not supported");
- }
-
- byte[] result = new byte[offset];
- System.arraycopy(precomputedDigest, 0, result, 0, offset);
- offset = 0;
-
- return result;
- }
- }
-
- public static final class SHA1 extends RSASignature {
- public SHA1() {
- super("SHA1");
- }
- }
-
- public static final class SHA256 extends RSASignature {
- public SHA256() {
- super("SHA-256");
- }
- }
-
- public static final class SHA384 extends RSASignature {
- public SHA384() {
- super("SHA-384");
- }
- }
-
- public static final class SHA512 extends RSASignature {
- public SHA512() {
- super("SHA-512");
- }
- }
-
- public static final class MD5 extends RSASignature {
- public MD5() {
- super("MD5");
- }
- }
-
- public static final class MD2 extends RSASignature {
- public MD2() {
- super("MD2");
- }
- }
-
- public static final class PSS extends RSASignature {
-
- private PSSParameterSpec pssParams = null;
-
- // Workaround: Cannot import raw public key to CNG. This signature
- // will be used for verification if key is not from MSCAPI.
- private Signature fallbackSignature;
-
- @Override
- protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
- super.engineInitSign(key);
- fallbackSignature = null;
- }
-
- @Override
- protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
- // This signature accepts only RSAPublicKey
- if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {
- throw new InvalidKeyException("Key type not supported");
- }
-
- this.privateKey = null;
-
- if (key instanceof sun.security.mscapi.RSAPublicKey) {
- fallbackSignature = null;
- publicKey = (sun.security.mscapi.RSAPublicKey) key;
- } else {
- if (fallbackSignature == null) {
- try {
- fallbackSignature = Signature.getInstance(
- "RSASSA-PSS", "SunRsaSign");
- } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
- throw new InvalidKeyException("Invalid key", e);
- }
- }
- fallbackSignature.initVerify(key);
- if (pssParams != null) {
- try {
- fallbackSignature.setParameter(pssParams);
- } catch (InvalidAlgorithmParameterException e) {
- throw new InvalidKeyException("Invalid params", e);
- }
- }
- publicKey = null;
- }
- resetDigest();
- }
-
- @Override
- protected void engineUpdate(byte b) throws SignatureException {
- ensureInit();
- if (fallbackSignature != null) {
- fallbackSignature.update(b);
- } else {
- messageDigest.update(b);
- }
- needsReset = true;
- }
-
- @Override
- protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
- ensureInit();
- if (fallbackSignature != null) {
- fallbackSignature.update(b, off, len);
- } else {
- messageDigest.update(b, off, len);
- }
- needsReset = true;
- }
-
- @Override
- protected void engineUpdate(ByteBuffer input) {
- try {
- ensureInit();
- } catch (SignatureException se) {
- // hack for working around API bug
- throw new RuntimeException(se.getMessage());
- }
- if (fallbackSignature != null) {
- try {
- fallbackSignature.update(input);
- } catch (SignatureException se) {
- // hack for working around API bug
- throw new RuntimeException(se.getMessage());
- }
- } else {
- messageDigest.update(input);
- }
- needsReset = true;
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- ensureInit();
- byte[] hash = getDigestValue();
- return signPssHash(hash, hash.length,
- pssParams.getSaltLength(),
- ((MGF1ParameterSpec)
- pssParams.getMGFParameters()).getDigestAlgorithm(),
- privateKey.getHCryptProvider(), privateKey.getHCryptKey());
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- ensureInit();
- if (fallbackSignature != null) {
- needsReset = false;
- return fallbackSignature.verify(sigBytes);
- } else {
- byte[] hash = getDigestValue();
- return verifyPssSignedHash(
- hash, hash.length,
- sigBytes, sigBytes.length,
- pssParams.getSaltLength(),
- ((MGF1ParameterSpec)
- pssParams.getMGFParameters()).getDigestAlgorithm(),
- publicKey.getHCryptProvider(),
- publicKey.getHCryptKey()
- );
- }
- }
-
- @Override
- protected void engineSetParameter(AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException {
- if (needsReset) {
- throw new ProviderException
- ("Cannot set parameters during operations");
- }
- this.pssParams = validateSigParams(params);
- if (fallbackSignature != null) {
- fallbackSignature.setParameter(params);
- }
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- AlgorithmParameters ap = null;
- if (this.pssParams != null) {
- try {
- ap = AlgorithmParameters.getInstance("RSASSA-PSS");
- ap.init(this.pssParams);
- } catch (GeneralSecurityException gse) {
- throw new ProviderException(gse.getMessage());
- }
- }
- return ap;
- }
-
- private void ensureInit() throws SignatureException {
- if (this.privateKey == null && this.publicKey == null
- && fallbackSignature == null) {
- throw new SignatureException("Missing key");
- }
- if (this.pssParams == null) {
- // Parameters are required for signature verification
- throw new SignatureException
- ("Parameters required for RSASSA-PSS signatures");
- }
- if (fallbackSignature == null && messageDigest == null) {
- // This could happen if initVerify(softKey), setParameter(),
- // and initSign() were called. No messageDigest. Create it.
- try {
- messageDigest = MessageDigest
- .getInstance(pssParams.getDigestAlgorithm());
- } catch (NoSuchAlgorithmException e) {
- throw new SignatureException(e);
- }
- }
- }
-
- /**
- * Validate the specified Signature PSS parameters.
- */
- private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
- throws InvalidAlgorithmParameterException {
-
- if (p == null) {
- throw new InvalidAlgorithmParameterException
- ("Parameters cannot be null");
- }
-
- if (!(p instanceof PSSParameterSpec)) {
- throw new InvalidAlgorithmParameterException
- ("parameters must be type PSSParameterSpec");
- }
-
- // no need to validate again if same as current signature parameters
- PSSParameterSpec params = (PSSParameterSpec) p;
- if (params == this.pssParams) return params;
-
- // now sanity check the parameter values
- if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
- throw new InvalidAlgorithmParameterException("Only supports MGF1");
-
- }
-
- if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
- throw new InvalidAlgorithmParameterException
- ("Only supports TrailerFieldBC(1)");
- }
-
- AlgorithmParameterSpec algSpec = params.getMGFParameters();
- if (!(algSpec instanceof MGF1ParameterSpec)) {
- throw new InvalidAlgorithmParameterException
- ("Only support MGF1ParameterSpec");
- }
-
- MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)algSpec;
-
- String msgHashAlg = params.getDigestAlgorithm()
- .toLowerCase(Locale.ROOT).replaceAll("-", "");
- if (msgHashAlg.equals("sha")) {
- msgHashAlg = "sha1";
- }
- String mgf1HashAlg = mgfSpec.getDigestAlgorithm()
- .toLowerCase(Locale.ROOT).replaceAll("-", "");
- if (mgf1HashAlg.equals("sha")) {
- mgf1HashAlg = "sha1";
- }
-
- if (!mgf1HashAlg.equals(msgHashAlg)) {
- throw new InvalidAlgorithmParameterException
- ("MGF1 hash must be the same as message hash");
- }
-
- return params;
- }
-
- /**
- * Sign hash using CNG API with HCRYPTKEY. Used by RSASSA-PSS.
- */
- private native static byte[] signPssHash(byte[] hash,
- int hashSize, int saltLength, String hashAlgorithm,
- long hCryptProv, long nCryptKey)
- throws SignatureException;
-
- /**
- * Verify a signed hash using CNG API with HCRYPTKEY. Used by RSASSA-PSS.
- * This method is not used now. See {@link #fallbackSignature}.
- */
- private native static boolean verifyPssSignedHash(byte[] hash, int hashSize,
- byte[] signature, int signatureSize,
- int saltLength, String hashAlgorithm,
- long hCryptProv, long hKey) throws SignatureException;
- }
-
- // initialize for signing. See JCA doc
- @Override
- protected void engineInitVerify(PublicKey key)
- throws InvalidKeyException
- {
- // This signature accepts only RSAPublicKey
- if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {
- throw new InvalidKeyException("Key type not supported");
- }
-
- java.security.interfaces.RSAPublicKey rsaKey =
- (java.security.interfaces.RSAPublicKey) key;
-
- if ((key instanceof sun.security.mscapi.RSAPublicKey) == false) {
-
- // convert key to MSCAPI format
-
- BigInteger modulus = rsaKey.getModulus();
- BigInteger exponent = rsaKey.getPublicExponent();
-
- // Check against the local and global values to make sure
- // the sizes are ok. Round up to the nearest byte.
- RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
- exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
-
- byte[] modulusBytes = modulus.toByteArray();
- byte[] exponentBytes = exponent.toByteArray();
-
- // Adjust key length due to sign bit
- int keyBitLength = (modulusBytes[0] == 0)
- ? (modulusBytes.length - 1) * 8
- : modulusBytes.length * 8;
-
- byte[] keyBlob = generatePublicKeyBlob(
- keyBitLength, modulusBytes, exponentBytes);
-
- try {
- publicKey = importPublicKey(keyBlob, keyBitLength);
-
- } catch (KeyStoreException e) {
- throw new InvalidKeyException(e);
- }
-
- } else {
- publicKey = (sun.security.mscapi.RSAPublicKey) key;
- }
-
- this.privateKey = null;
- resetDigest();
- }
-
- // initialize for signing. See JCA doc
- @Override
- protected void engineInitSign(PrivateKey key) throws InvalidKeyException
- {
- // This signature accepts only RSAPrivateKey
- if ((key instanceof sun.security.mscapi.RSAPrivateKey) == false) {
- throw new InvalidKeyException("Key type not supported");
- }
- privateKey = (sun.security.mscapi.RSAPrivateKey) key;
-
- // Check against the local and global values to make sure
- // the sizes are ok. Round up to nearest byte.
- RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
- null, RSAKeyPairGenerator.KEY_SIZE_MIN,
- RSAKeyPairGenerator.KEY_SIZE_MAX);
-
- this.publicKey = null;
- resetDigest();
- }
-
- /**
- * Resets the message digest if needed.
- */
- protected void resetDigest() {
- if (needsReset) {
- if (messageDigest != null) {
- messageDigest.reset();
- }
- needsReset = false;
- }
- }
-
- protected byte[] getDigestValue() throws SignatureException {
- needsReset = false;
- return messageDigest.digest();
- }
-
- protected void setDigestName(String name) {
- messageDigestAlgorithm = name;
- }
-
- /**
- * Updates the data to be signed or verified
- * using the specified byte.
- *
- * @param b the byte to use for the update.
- *
- * @exception SignatureException if the engine is not initialized
- * properly.
- */
- @Override
- protected void engineUpdate(byte b) throws SignatureException
- {
- messageDigest.update(b);
- needsReset = true;
- }
-
- /**
- * Updates the data to be signed or verified, using the
- * specified array of bytes, starting at the specified offset.
- *
- * @param b the array of bytes
- * @param off the offset to start from in the array of bytes
- * @param len the number of bytes to use, starting at offset
- *
- * @exception SignatureException if the engine is not initialized
- * properly
- */
- @Override
- protected void engineUpdate(byte[] b, int off, int len)
- throws SignatureException
- {
- messageDigest.update(b, off, len);
- needsReset = true;
- }
-
- /**
- * Updates the data to be signed or verified, using the
- * specified ByteBuffer.
- *
- * @param input the ByteBuffer
- */
- @Override
- protected void engineUpdate(ByteBuffer input)
- {
- messageDigest.update(input);
- needsReset = true;
- }
-
- /**
- * Returns the signature bytes of all the data
- * updated so far.
- * The format of the signature depends on the underlying
- * signature scheme.
- *
- * @return the signature bytes of the signing operation's result.
- *
- * @exception SignatureException if the engine is not
- * initialized properly or if this signature algorithm is unable to
- * process the input data provided.
- */
- @Override
- protected byte[] engineSign() throws SignatureException {
-
- byte[] hash = getDigestValue();
-
- // Omit the hash OID when generating a Raw signature
- boolean noHashOID = this instanceof Raw;
-
- // Sign hash using MS Crypto APIs
-
- byte[] result = signHash(noHashOID, hash, hash.length,
- messageDigestAlgorithm, privateKey.getHCryptProvider(),
- privateKey.getHCryptKey());
-
- // Convert signature array from little endian to big endian
- return convertEndianArray(result);
- }
-
- /**
- * Convert array from big endian to little endian, or vice versa.
- */
- private byte[] convertEndianArray(byte[] byteArray)
- {
- if (byteArray == null || byteArray.length == 0)
- return byteArray;
-
- byte [] retval = new byte[byteArray.length];
-
- // make it big endian
- for (int i=0;i < byteArray.length;i++)
- retval[i] = byteArray[byteArray.length - i - 1];
-
- return retval;
- }
-
- /**
- * Sign hash using Microsoft Crypto API with HCRYPTKEY.
- * The returned data is in little-endian.
- */
- private native static byte[] signHash(boolean noHashOID, byte[] hash,
- int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)
- throws SignatureException;
-
- /**
- * Verify a signed hash using Microsoft Crypto API with HCRYPTKEY.
- */
- private native static boolean verifySignedHash(byte[] hash, int hashSize,
- String hashAlgorithm, byte[] signature, int signatureSize,
- long hCryptProv, long hCryptKey) throws SignatureException;
-
- /**
- * Verifies the passed-in signature.
- *
- * @param sigBytes the signature bytes to be verified.
- *
- * @return true if the signature was verified, false if not.
- *
- * @exception SignatureException if the engine is not
- * initialized properly, the passed-in signature is improperly
- * encoded or of the wrong type, if this signature algorithm is unable to
- * process the input data provided, etc.
- */
- @Override
- protected boolean engineVerify(byte[] sigBytes)
- throws SignatureException
- {
- byte[] hash = getDigestValue();
-
- return verifySignedHash(hash, hash.length,
- messageDigestAlgorithm, convertEndianArray(sigBytes),
- sigBytes.length, publicKey.getHCryptProvider(),
- publicKey.getHCryptKey());
- }
-
- /**
- * Sets the specified algorithm parameter to the specified
- * value. This method supplies a general-purpose mechanism through
- * which it is possible to set the various parameters of this object.
- * A parameter may be any settable parameter for the algorithm, such as
- * a parameter size, or a source of random bits for signature generation
- * (if appropriate), or an indication of whether or not to perform
- * a specific but optional computation. A uniform algorithm-specific
- * naming scheme for each parameter is desirable but left unspecified
- * at this time.
- *
- * @param param the string identifier of the parameter.
- *
- * @param value the parameter value.
- *
- * @exception InvalidParameterException if <code>param</code> is an
- * invalid parameter for this signature algorithm engine,
- * the parameter is already set
- * and cannot be set again, a security exception occurs, and so on.
- *
- * @deprecated Replaced by {@link
- * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
- * engineSetParameter}.
- */
- @Override
- @Deprecated
- protected void engineSetParameter(String param, Object value)
- throws InvalidParameterException
- {
- throw new InvalidParameterException("Parameter not supported");
- }
-
- /**
- * Sets this signature engine with the specified algorithm parameter.
- *
- * @param params the parameters
- *
- * @exception InvalidAlgorithmParameterException if the given
- * parameter is invalid
- */
- @Override
- protected void engineSetParameter(AlgorithmParameterSpec params)
- throws InvalidAlgorithmParameterException
- {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("No parameter accepted");
- }
- }
-
- /**
- * Gets the value of the specified algorithm parameter.
- * This method supplies a general-purpose mechanism through which it
- * is possible to get the various parameters of this object. A parameter
- * may be any settable parameter for the algorithm, such as a parameter
- * size, or a source of random bits for signature generation (if
- * appropriate), or an indication of whether or not to perform a
- * specific but optional computation. A uniform algorithm-specific
- * naming scheme for each parameter is desirable but left unspecified
- * at this time.
- *
- * @param param the string name of the parameter.
- *
- * @return the object that represents the parameter value, or null if
- * there is none.
- *
- * @exception InvalidParameterException if <code>param</code> is an
- * invalid parameter for this engine, or another exception occurs while
- * trying to get this parameter.
- *
- * @deprecated
- */
- @Override
- @Deprecated
- protected Object engineGetParameter(String param)
- throws InvalidParameterException
- {
- throw new InvalidParameterException("Parameter not supported");
- }
-
- /**
- * Gets the algorithm parameter from this signature engine.
- *
- * @return the parameter, or null if no parameter is used.
- */
- @Override
- protected AlgorithmParameters engineGetParameters() {
- return null;
- }
-
- /**
- * Generates a public-key BLOB from a key's components.
- */
- // used by RSACipher
- static native byte[] generatePublicKeyBlob(
- int keyBitLength, byte[] modulus, byte[] publicExponent)
- throws InvalidKeyException;
-
- /**
- * Imports a public-key BLOB.
- */
- // used by RSACipher
- static native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize)
- throws KeyStoreException;
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java Thu Dec 13 09:02:52 2018 +0000
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java Thu Dec 13 17:28:19 2018 +0800
@@ -33,7 +33,6 @@
import java.security.ProviderException;
import java.util.HashMap;
import java.util.Arrays;
-import java.util.Map;
import static sun.security.util.SecurityConstants.PROVIDER_VER;
@@ -86,36 +85,36 @@
}
} else if (type.equals("KeyStore")) {
if (algo.equals("Windows-MY")) {
- return new KeyStore.MY();
+ return new CKeyStore.MY();
} else if (algo.equals("Windows-ROOT")) {
- return new KeyStore.ROOT();
+ return new CKeyStore.ROOT();
}
} else if (type.equals("Signature")) {
if (algo.equals("NONEwithRSA")) {
- return new RSASignature.Raw();
+ return new CSignature.NONEwithRSA();
} else if (algo.equals("SHA1withRSA")) {
- return new RSASignature.SHA1();
+ return new CSignature.SHA1withRSA();
} else if (algo.equals("SHA256withRSA")) {
- return new RSASignature.SHA256();
+ return new CSignature.SHA256withRSA();
} else if (algo.equals("SHA384withRSA")) {
- return new RSASignature.SHA384();
+ return new CSignature.SHA384withRSA();
} else if (algo.equals("SHA512withRSA")) {
- return new RSASignature.SHA512();
+ return new CSignature.SHA512withRSA();
} else if (algo.equals("MD5withRSA")) {
- return new RSASignature.MD5();
+ return new CSignature.MD5withRSA();
} else if (algo.equals("MD2withRSA")) {
- return new RSASignature.MD2();
+ return new CSignature.MD2withRSA();
} else if (algo.equals("RSASSA-PSS")) {
- return new RSASignature.PSS();
+ return new CSignature.PSS();
}
} else if (type.equals("KeyPairGenerator")) {
if (algo.equals("RSA")) {
- return new RSAKeyPairGenerator();
+ return new CKeyPairGenerator.RSA();
}
} else if (type.equals("Cipher")) {
if (algo.equals("RSA") ||
algo.equals("RSA/ECB/PKCS1Padding")) {
- return new RSACipher();
+ return new CRSACipher();
}
}
} catch (Exception ex) {
@@ -147,47 +146,47 @@
* Key store
*/
putService(new ProviderService(p, "KeyStore",
- "Windows-MY", "sun.security.mscapi.KeyStore$MY"));
+ "Windows-MY", "sun.security.mscapi.CKeyStore$MY"));
putService(new ProviderService(p, "KeyStore",
- "Windows-ROOT", "sun.security.mscapi.KeyStore$ROOT"));
+ "Windows-ROOT", "sun.security.mscapi.CKeyStore$ROOT"));
/*
* Signature engines
*/
HashMap<String, String> attrs = new HashMap<>(1);
- attrs.put("SupportedKeyClasses", "sun.security.mscapi.Key");
+ attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey");
// NONEwithRSA must be supplied with a pre-computed message digest.
// Only the following digest algorithms are supported: MD5, SHA-1,
// SHA-256, SHA-384, SHA-512 and a special-purpose digest
// algorithm which is a concatenation of SHA-1 and MD5 digests.
putService(new ProviderService(p, "Signature",
- "NONEwithRSA", "sun.security.mscapi.RSASignature$Raw",
+ "NONEwithRSA", "sun.security.mscapi.CSignature$NONEwithRSA",
null, attrs));
putService(new ProviderService(p, "Signature",
- "SHA1withRSA", "sun.security.mscapi.RSASignature$SHA1",
+ "SHA1withRSA", "sun.security.mscapi.CSignature$SHA1withRSA",
null, attrs));
putService(new ProviderService(p, "Signature",
- "SHA256withRSA", "sun.security.mscapi.RSASignature$SHA256",
+ "SHA256withRSA", "sun.security.mscapi.CSignature$SHA256withRSA",
new String[] { "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11" },
attrs));
putService(new ProviderService(p, "Signature",
- "SHA384withRSA", "sun.security.mscapi.RSASignature$SHA384",
+ "SHA384withRSA", "sun.security.mscapi.CSignature$SHA384withRSA",
new String[] { "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12" },
attrs));
putService(new ProviderService(p, "Signature",
- "SHA512withRSA", "sun.security.mscapi.RSASignature$SHA512",
+ "SHA512withRSA", "sun.security.mscapi.CSignature$SHA512withRSA",
new String[] { "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13" },
attrs));
putService(new ProviderService(p, "Signature",
- "RSASSA-PSS", "sun.security.mscapi.RSASignature$PSS",
+ "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS",
new String[] { "1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10" },
attrs));
putService(new ProviderService(p, "Signature",
- "MD5withRSA", "sun.security.mscapi.RSASignature$MD5",
+ "MD5withRSA", "sun.security.mscapi.CSignature$MD5withRSA",
null, attrs));
putService(new ProviderService(p, "Signature",
- "MD2withRSA", "sun.security.mscapi.RSASignature$MD2",
+ "MD2withRSA", "sun.security.mscapi.CSignature$MD2withRSA",
null, attrs));
/*
@@ -196,7 +195,7 @@
attrs.clear();
attrs.put("KeySize", "16384");
putService(new ProviderService(p, "KeyPairGenerator",
- "RSA", "sun.security.mscapi.RSAKeyPairGenerator",
+ "RSA", "sun.security.mscapi.CKeyPairGenerator$RSA",
null, attrs));
/*
@@ -205,12 +204,12 @@
attrs.clear();
attrs.put("SupportedModes", "ECB");
attrs.put("SupportedPaddings", "PKCS1PADDING");
- attrs.put("SupportedKeyClasses", "sun.security.mscapi.Key");
+ attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey");
putService(new ProviderService(p, "Cipher",
- "RSA", "sun.security.mscapi.RSACipher",
+ "RSA", "sun.security.mscapi.CRSACipher",
null, attrs));
putService(new ProviderService(p, "Cipher",
- "RSA/ECB/PKCS1Padding", "sun.security.mscapi.RSACipher",
+ "RSA/ECB/PKCS1Padding", "sun.security.mscapi.CRSACipher",
null, attrs));
return null;
}
--- a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Thu Dec 13 09:02:52 2018 +0000
+++ b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Thu Dec 13 17:28:19 2018 +0800
@@ -37,13 +37,15 @@
#include <wincrypt.h>
#include <stdio.h>
#include <memory>
-#include "sun_security_mscapi_Key.h"
-#include "sun_security_mscapi_KeyStore.h"
+#include "sun_security_mscapi_CKey.h"
+#include "sun_security_mscapi_CKeyStore.h"
#include "sun_security_mscapi_PRNG.h"
-#include "sun_security_mscapi_RSACipher.h"
-#include "sun_security_mscapi_RSAKeyPairGenerator.h"
-#include "sun_security_mscapi_RSAPublicKey.h"
-#include "sun_security_mscapi_RSASignature.h"
+#include "sun_security_mscapi_CRSACipher.h"
+#include "sun_security_mscapi_CKeyPairGenerator_RSA.h"
+#include "sun_security_mscapi_CPublicKey.h"
+#include "sun_security_mscapi_CPublicKey_CRSAPublicKey.h"
+#include "sun_security_mscapi_CSignature.h"
+#include "sun_security_mscapi_CSignature_RSA.h"
#define OID_EKU_ANY "2.5.29.37.0"
@@ -64,7 +66,7 @@
}
//#define PP(fmt, ...) \
-// fprintf(stdout, "SSPI (%ld): ", __LINE__); \
+// fprintf(stdout, "MSCAPI (%ld): ", __LINE__); \
// fprintf(stdout, fmt, ##__VA_ARGS__); \
// fprintf(stdout, "\n"); \
// fflush(stdout)
@@ -79,13 +81,27 @@
//void dump(LPSTR title, PBYTE data, DWORD len)
//{
// printf("==== %s ====\n", title);
-// for (DWORD i = 0; i < len; i++) {
-// if (i != 0 && i % 16 == 0) {
-// printf("\n");
+// for (DWORD i = 0; i < len; i+=16) {
+// printf("%04x: ", i);
+// for (int j = 0; j < 16; j++) {
+// if (j == 8) {
+// printf(" ");
+// }
+// if (i + j < len) {
+// printf("%02X ", *(data + i + j) & 0xff);
+// } else {
+// printf(" ");
+// }
// }
-// printf("%02X ", *(data + i) & 0xff);
+// for (int j = 0; j < 16; j++) {
+// if (i + j < len) {
+// int k = *(data + i + j) & 0xff;
+// if (k < 32 || k > 127) printf(".");
+// else printf("%c", (char)k);
+// }
+// }
+// printf("\n");
// }
-// printf("\n");
//}
/*
@@ -248,7 +264,7 @@
JNIEXPORT jlong JNICALL Java_sun_security_mscapi_PRNG_getContext
(JNIEnv *env, jclass clazz) {
HCRYPTPROV hCryptProv = NULL;
- if(::CryptAcquireContext(
+ if(::CryptAcquireContext( //deprecated
&hCryptProv,
NULL,
NULL,
@@ -269,7 +285,7 @@
JNIEXPORT void JNICALL Java_sun_security_mscapi_PRNG_releaseContext
(JNIEnv *env, jclass clazz, jlong ctxt) {
if (ctxt) {
- ::CryptReleaseContext((HCRYPTPROV)ctxt, 0);
+ ::CryptReleaseContext((HCRYPTPROV)ctxt, 0); //deprecated
}
}
@@ -304,7 +320,7 @@
__leave;
}
- if (::CryptGenRandom(
+ if (::CryptGenRandom( //deprecated
hCryptProv,
length,
(BYTE *) reseedBytes) == FALSE) {
@@ -330,7 +346,7 @@
__leave;
}
- if (::CryptGenRandom(
+ if (::CryptGenRandom( //deprecated
hCryptProv,
length,
(BYTE *) seedBytes) == FALSE) {
@@ -359,11 +375,11 @@
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: loadKeysOrCertificateChains
- * Signature: (Ljava/lang/String;Ljava/util/Collection;)V
+ * Signature: (Ljava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateChains
(JNIEnv *env, jobject obj, jstring jCertStoreName)
{
/**
@@ -460,7 +476,7 @@
else
{
if (bCallerFreeProv == TRUE) {
- ::CryptReleaseContext(hCryptProv, NULL);
+ ::CryptReleaseContext(hCryptProv, NULL); // deprecated
bCallerFreeProv = FALSE;
}
@@ -473,18 +489,18 @@
else
{
// Private key is available
- BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey);
+ BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey); //deprecated
// Skip certificate if cannot find private key
if (bGetUserKey == FALSE) {
if (bCallerFreeProv)
- ::CryptReleaseContext(hCryptProv, NULL);
+ ::CryptReleaseContext(hCryptProv, NULL); // deprecated
continue;
}
// Set cipher mode to ECB
DWORD dwCipherMode = CRYPT_MODE_ECB;
- ::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL);
+ ::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL); //deprecated
// If the private key is present in smart card, we may not be able to
// determine the key length by using the private key handle. However,
@@ -570,9 +586,8 @@
// Determine key type: RSA or DSA
DWORD dwData = CALG_RSA_KEYX;
DWORD dwSize = sizeof(DWORD);
- ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData,
+ ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData, //deprecated
&dwSize, NULL);
-
if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
{
// Generate RSA certificate chain and store into cert
@@ -614,18 +629,18 @@
(JNIEnv *env, jclass clazz, jlong hCryptProv, jlong hCryptKey)
{
if (hCryptKey != NULL)
- ::CryptDestroyKey((HCRYPTKEY) hCryptKey);
+ ::CryptDestroyKey((HCRYPTKEY) hCryptKey); // deprecated
if (hCryptProv != NULL)
- ::CryptReleaseContext((HCRYPTPROV) hCryptProv, NULL);
+ ::CryptReleaseContext((HCRYPTPROV) hCryptProv, NULL); // deprecated
}
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature
* Method: signHash
* Signature: (Z[BILjava/lang/String;JJ)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash
(JNIEnv *env, jclass clazz, jboolean noHashOID, jbyteArray jHash,
jint jHashSize, jstring jHashAlgorithm, jlong hCryptProv,
jlong hCryptKey)
@@ -642,7 +657,7 @@
ALG_ID algId = MapHashAlgorithm(env, jHashAlgorithm);
// Acquire a hash object handle.
- if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash) == FALSE)
+ if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash) == FALSE) //deprecated
{
// Failover to using the PROV_RSA_AES CSP
@@ -651,11 +666,11 @@
pbData[0] = '\0';
// Get name of the key container
- ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
+ ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle
- if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
+ if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
PROV_RSA_AES, 0) == FALSE)
{
@@ -664,7 +679,7 @@
}
// Acquire a hash object handle.
- if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
+ if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0, //deprecated
&hHash) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -680,7 +695,7 @@
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
// Set hash value in the hash object
- if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)pHashBuffer, NULL) == FALSE)
+ if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)pHashBuffer, NULL) == FALSE) //deprecated
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -691,7 +706,7 @@
ALG_ID dwAlgId;
DWORD dwAlgIdLen = sizeof(ALG_ID);
- if (! ::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {
+ if (! ::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) { //deprecated
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -708,7 +723,7 @@
dwFlags = CRYPT_NOHASHOID; // omit hash OID in NONEwithRSA signature
}
- if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE)
+ if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE) //deprecated
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -718,7 +733,7 @@
if (pSignedHashBuffer == NULL) {
__leave;
}
- if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
+ if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE) //deprecated
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
@@ -741,21 +756,21 @@
delete [] pHashBuffer;
if (hHash)
- ::CryptDestroyHash(hHash);
+ ::CryptDestroyHash(hHash); //deprecated
if (hCryptProvAlt)
- ::CryptReleaseContext(hCryptProvAlt, 0);
+ ::CryptReleaseContext(hCryptProvAlt, 0); // deprecated
}
return jSignedHash;
}
/*
- * Class: sun_security_mscapi_RSASignature_PSS
- * Method: signPssHash
+ * Class: sun_security_mscapi_CSignature
+ * Method: signCngHash
* Signature: ([BIILjava/lang/String;JJ)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_00024PSS_signPssHash
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signCngHash
(JNIEnv *env, jclass clazz, jbyteArray jHash,
jint jHashSize, jint saltLen, jstring jHashAlgorithm, jlong hCryptProv,
jlong hCryptKey)
@@ -839,11 +854,11 @@
}
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature
* Method: verifySignedHash
* Signature: ([BIL/java/lang/String;[BIJJ)Z
*/
-JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHash
+JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_CSignature_verifySignedHash
(JNIEnv *env, jclass clazz, jbyteArray jHash, jint jHashSize,
jstring jHashAlgorithm, jbyteArray jSignedHash, jint jSignedHashSize,
jlong hCryptProv, jlong hCryptKey)
@@ -871,11 +886,11 @@
pbData[0] = '\0';
// Get name of the key container
- ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
+ ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle
- if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
+ if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
PROV_RSA_AES, 0) == FALSE)
{
@@ -907,7 +922,7 @@
pSignedHashBuffer);
// Set hash value in the hash object
- if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*) pHashBuffer, NULL)
+ if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*) pHashBuffer, NULL) //deprecated
== FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -918,7 +933,7 @@
// public key algorithm, so AT_SIGNATURE is used.
// Verify the signature
- if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer,
+ if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer, //deprecated
dwSignedHashBufferLen, (HCRYPTKEY) hCryptKey, NULL, 0) == TRUE)
{
result = JNI_TRUE;
@@ -934,26 +949,26 @@
delete [] pHashBuffer;
if (hHash)
- ::CryptDestroyHash(hHash);
+ ::CryptDestroyHash(hHash); //deprecated
if (hCryptProvAlt)
- ::CryptReleaseContext(hCryptProvAlt, 0);
+ ::CryptReleaseContext(hCryptProvAlt, 0); // deprecated
}
return result;
}
/*
- * Class: sun_security_mscapi_RSASignature_PSS
- * Method: verifyPssSignedHash
+ * Class: sun_security_mscapi_CSignature
+ * Method: verifyCngSignedHash
* Signature: ([BI[BIILjava/lang/String;JJ)Z
*/
-JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_00024PSS_verifyPssSignedHash
+JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_CSignature_verifyCngSignedHash
(JNIEnv *env, jclass clazz,
jbyteArray jHash, jint jHashSize,
jbyteArray jSignedHash, jint jSignedHashSize,
jint saltLen, jstring jHashAlgorithm,
- jlong hCryptProv, jlong hKey)
+ jlong hCryptProv, jlong hCryptKey)
{
jbyte* pHashBuffer = NULL;
jbyte* pSignedHashBuffer = NULL;
@@ -966,7 +981,7 @@
NULL,
&hk,
hCryptProv,
- hKey,
+ hCryptKey,
NULL,
0));
@@ -987,17 +1002,12 @@
BCRYPT_PSS_PADDING_INFO pssInfo;
pssInfo.pszAlgId = MapHashIdentifier(env, jHashAlgorithm);
pssInfo.cbSalt = saltLen;
-
if (pssInfo.pszAlgId == NULL) {
ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION,
"Unrecognised hash algorithm");
__leave;
}
- // For RSA, the hash encryption algorithm is normally the same as the
- // public key algorithm, so AT_SIGNATURE is used.
-
- // Verify the signature
if (::NCryptVerifySignature(hk, &pssInfo,
(BYTE *) pHashBuffer, jHashSize,
(BYTE *) pSignedHashBuffer, jSignedHashSize,
@@ -1023,12 +1033,12 @@
}
/*
- * Class: sun_security_mscapi_RSAKeyPairGenerator
- * Method: generateRSAKeyPair
- * Signature: (ILjava/lang/String;)Lsun/security/mscapi/RSAKeyPair;
+ * Class: sun_security_mscapi_CKeyPairGenerator_RSA
+ * Method: generateCKeyPair
+ * Signature: (Ljava/lang/String;ILjava/lang/String;)Lsun/security/mscapi/CKeyPair;
*/
-JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateRSAKeyPair
- (JNIEnv *env, jclass clazz, jint keySize, jstring keyContainerName)
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CKeyPairGenerator_00024RSA_generateCKeyPair
+ (JNIEnv *env, jclass clazz, jstring alg, jint keySize, jstring keyContainerName)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKeyPair;
@@ -1046,7 +1056,7 @@
// Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures.
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -1055,7 +1065,7 @@
{
// Failover to using the default CSP (PROV_RSA_FULL)
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -1067,8 +1077,8 @@
}
}
- // Generate an RSA keypair
- if(::CryptGenKey(
+ // Generate an keypair
+ if(::CryptGenKey( //deprecated
hCryptProv,
AT_KEYEXCHANGE,
dwFlags,
@@ -1078,22 +1088,22 @@
__leave;
}
- // Get the method ID for the RSAKeyPair constructor
- jclass clazzRSAKeyPair =
- env->FindClass("sun/security/mscapi/RSAKeyPair");
- if (clazzRSAKeyPair == NULL) {
+ // Get the method ID for the CKeyPair constructor
+ jclass clazzCKeyPair =
+ env->FindClass("sun/security/mscapi/CKeyPair");
+ if (clazzCKeyPair == NULL) {
__leave;
}
- jmethodID mNewRSAKeyPair =
- env->GetMethodID(clazzRSAKeyPair, "<init>", "(JJI)V");
- if (mNewRSAKeyPair == NULL) {
+ jmethodID mNewCKeyPair =
+ env->GetMethodID(clazzCKeyPair, "<init>", "(Ljava/lang/String;JJI)V");
+ if (mNewCKeyPair == NULL) {
__leave;
}
- // Create a new RSA keypair
- keypair = env->NewObject(clazzRSAKeyPair, mNewRSAKeyPair,
- (jlong) hCryptProv, (jlong) hKeyPair, keySize);
+ // Create a new keypair
+ keypair = env->NewObject(clazzCKeyPair, mNewCKeyPair,
+ alg, (jlong) hCryptProv, (jlong) hKeyPair, keySize);
}
__finally
@@ -1109,18 +1119,18 @@
}
/*
- * Class: sun_security_mscapi_Key
+ * Class: sun_security_mscapi_CKey
* Method: getContainerName
* Signature: (J)Ljava/lang/String;
*/
-JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getContainerName
+JNIEXPORT jstring JNICALL Java_sun_security_mscapi_CKey_getContainerName
(JNIEnv *env, jclass jclazz, jlong hCryptProv)
{
DWORD cbData = 256;
BYTE pbData[256];
pbData[0] = '\0';
- ::CryptGetProvParam(
+ ::CryptGetProvParam( //deprecated
(HCRYPTPROV)hCryptProv,
PP_CONTAINER,
(BYTE *)pbData,
@@ -1131,17 +1141,17 @@
}
/*
- * Class: sun_security_mscapi_Key
+ * Class: sun_security_mscapi_CKey
* Method: getKeyType
* Signature: (J)Ljava/lang/String;
*/
-JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getKeyType
+JNIEXPORT jstring JNICALL Java_sun_security_mscapi_CKey_getKeyType
(JNIEnv *env, jclass jclazz, jlong hCryptKey)
{
ALG_ID dwAlgId;
DWORD dwAlgIdLen = sizeof(ALG_ID);
- if (::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {
+ if (::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) { //deprecated
if (CALG_RSA_SIGN == dwAlgId) {
return env->NewStringUTF("Signature");
@@ -1161,11 +1171,11 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: storeCertificate
* Signature: (Ljava/lang/String;Ljava/lang/String;[BIJJ)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_storeCertificate
(JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName,
jbyteArray jCertEncoding, jint jCertEncodingSize, jlong hCryptProv,
jlong hCryptKey)
@@ -1240,7 +1250,7 @@
DWORD dwDataLen;
// Get the name of the key container
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_CONTAINER,
NULL,
@@ -1256,7 +1266,7 @@
__leave;
}
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_CONTAINER,
(BYTE *) pszContainerName,
@@ -1283,7 +1293,7 @@
// Get the name of the provider
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_NAME,
NULL,
@@ -1299,7 +1309,7 @@
__leave;
}
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_NAME,
(BYTE *) pszProviderName,
@@ -1325,7 +1335,7 @@
keyProviderInfo.pwszProvName = pwszProviderName;
// Get and set the type of the provider
- if (! ::CryptGetProvParam(
+ if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv,
PP_PROVTYPE,
(LPBYTE) &keyProviderInfo.dwProvType,
@@ -1344,7 +1354,7 @@
keyProviderInfo.rgProvParam = NULL;
// Get the key's algorithm ID
- if (! ::CryptGetKeyParam(
+ if (! ::CryptGetKeyParam( //deprecated
(HCRYPTKEY) hCryptKey,
KP_ALGID,
(LPBYTE) &keyProviderInfo.dwKeySpec,
@@ -1423,11 +1433,11 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: removeCertificate
* Signature: (Ljava/lang/String;Ljava/lang/String;[BI)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_removeCertificate
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_removeCertificate
(JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName,
jbyteArray jCertEncoding, jint jCertEncodingSize) {
@@ -1539,11 +1549,11 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: destroyKeyContainer
* Signature: (Ljava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_destroyKeyContainer
+JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_destroyKeyContainer
(JNIEnv *env, jobject clazz, jstring keyContainerName)
{
HCRYPTPROV hCryptProv = NULL;
@@ -1565,7 +1575,7 @@
}
// Acquire a CSP context (to the key container).
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -1588,11 +1598,11 @@
}
/*
- * Class: sun_security_mscapi_RSACipher
+ * Class: sun_security_mscapi_CRSACipher
* Method: encryptDecrypt
* Signature: ([BIJZ)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CRSACipher_encryptDecrypt
(JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
jboolean doEncrypt)
{
@@ -1614,7 +1624,7 @@
if (doEncrypt == JNI_TRUE) {
// encrypt
- if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData,
+ if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
&dwDataLen, dwBufLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError());
@@ -1637,7 +1647,7 @@
}
// decrypt
- if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData,
+ if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
&dwBufLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError());
@@ -1661,11 +1671,11 @@
}
/*
- * Class: sun_security_mscapi_RSAPublicKey
+ * Class: sun_security_mscapi_CPublicKey
* Method: getPublicKeyBlob
* Signature: (J)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyBlob
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_getPublicKeyBlob
(JNIEnv *env, jobject clazz, jlong hCryptKey) {
jbyteArray blob = NULL;
@@ -1676,7 +1686,7 @@
{
// Determine the size of the blob
- if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL,
+ if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL, //deprecated
&dwBlobLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError());
@@ -1689,7 +1699,7 @@
}
// Generate key blob
- if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
+ if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, //deprecated
pbKeyBlob, &dwBlobLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError());
@@ -1712,11 +1722,11 @@
}
/*
- * Class: sun_security_mscapi_RSAPublicKey
+ * Class: sun_security_mscapi_CPublicKey_CRSAPublicKey
* Method: getExponent
* Signature: ([B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getExponent
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublicKey_getExponent
(JNIEnv *env, jobject clazz, jbyteArray jKeyBlob) {
jbyteArray exponent = NULL;
@@ -1768,11 +1778,11 @@
}
/*
- * Class: sun_security_mscapi_RSAPublicKey
+ * Class: sun_security_mscapi_CPublicKey_CRSAPublicKey
* Method: getModulus
* Signature: ([B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getModulus
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublicKey_getModulus
(JNIEnv *env, jobject clazz, jbyteArray jKeyBlob) {
jbyteArray modulus = NULL;
@@ -2041,11 +2051,11 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
- * Method: generatePrivateKeyBlob
+ * Class: sun_security_mscapi_CKeyStore
+ * Method: generateRSAPrivateKeyBlob
* Signature: (I[B[B[B[B[B[B[B[B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_KeyStore_generatePrivateKeyBlob
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CKeyStore_generateRSAPrivateKeyBlob
(JNIEnv *env, jobject clazz,
jint jKeyBitLength,
jbyteArray jModulus,
@@ -2063,11 +2073,11 @@
}
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature_RSA
* Method: generatePublicKeyBlob
* Signature: (I[B[B)[B
*/
-JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_generatePublicKeyBlob
+JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_00024RSA_generatePublicKeyBlob
(JNIEnv *env, jclass clazz,
jint jKeyBitLength,
jbyteArray jModulus,
@@ -2078,13 +2088,13 @@
}
/*
- * Class: sun_security_mscapi_KeyStore
+ * Class: sun_security_mscapi_CKeyStore
* Method: storePrivateKey
- * Signature: ([BLjava/lang/String;I)Lsun/security/mscapi/RSAPrivateKey;
+ * Signature: (Ljava/lang/String;[BLjava/lang/String;I)Lsun/security/mscapi/CPrivateKey;
*/
-JNIEXPORT jobject JNICALL Java_sun_security_mscapi_KeyStore_storePrivateKey
- (JNIEnv *env, jobject clazz, jbyteArray keyBlob, jstring keyContainerName,
- jint keySize)
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CKeyStore_storePrivateKey
+ (JNIEnv *env, jobject clazz, jstring alg, jbyteArray keyBlob,
+ jstring keyContainerName, jint keySize)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
@@ -2106,7 +2116,7 @@
}
// Acquire a CSP context (create a new key container).
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
pszKeyContainerName,
NULL,
@@ -2118,7 +2128,7 @@
}
// Import the private key
- if (::CryptImportKey(
+ if (::CryptImportKey( //deprecated
hCryptProv,
pbKeyBlob,
dwBlobLen,
@@ -2130,22 +2140,23 @@
__leave;
}
- // Get the method ID for the RSAPrivateKey constructor
- jclass clazzRSAPrivateKey =
- env->FindClass("sun/security/mscapi/RSAPrivateKey");
- if (clazzRSAPrivateKey == NULL) {
+ // Get the method ID for the CPrivateKey constructor
+ jclass clazzCPrivateKey =
+ env->FindClass("sun/security/mscapi/CPrivateKey");
+ if (clazzCPrivateKey == NULL) {
__leave;
}
- jmethodID mNewRSAPrivateKey =
- env->GetMethodID(clazzRSAPrivateKey, "<init>", "(JJI)V");
- if (mNewRSAPrivateKey == NULL) {
+ jmethodID mNewCPrivateKey =
+ env->GetStaticMethodID(clazzCPrivateKey, "of",
+ "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPrivateKey;");
+ if (mNewCPrivateKey == NULL) {
__leave;
}
- // Create a new RSA private key
- privateKey = env->NewObject(clazzRSAPrivateKey, mNewRSAPrivateKey,
- (jlong) hCryptProv, (jlong) hKey, keySize);
+ // Create a new private key
+ privateKey = env->CallStaticObjectMethod(clazzCPrivateKey, mNewCPrivateKey,
+ alg, (jlong) hCryptProv, (jlong) hKey, keySize);
}
__finally
@@ -2165,12 +2176,12 @@
}
/*
- * Class: sun_security_mscapi_RSASignature
+ * Class: sun_security_mscapi_CSignature
* Method: importPublicKey
- * Signature: ([BI)Lsun/security/mscapi/RSAPublicKey;
+ * Signature: (Ljava/lang/String;[BI)Lsun/security/mscapi/CPublicKey;
*/
-JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
- (JNIEnv *env, jclass clazz, jbyteArray keyBlob, jint keySize)
+JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CSignature_importPublicKey
+ (JNIEnv *env, jclass clazz, jstring alg, jbyteArray keyBlob, jint keySize)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
@@ -2189,7 +2200,7 @@
// Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures.
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
NULL,
NULL,
@@ -2198,7 +2209,7 @@
{
// Failover to using the default CSP (PROV_RSA_FULL)
- if (::CryptAcquireContext(
+ if (::CryptAcquireContext( //deprecated
&hCryptProv,
NULL,
NULL,
@@ -2211,7 +2222,7 @@
}
// Import the public key
- if (::CryptImportKey(
+ if (::CryptImportKey( //deprecated
hCryptProv,
pbKeyBlob,
dwBlobLen,
@@ -2223,22 +2234,23 @@
__leave;
}
- // Get the method ID for the RSAPublicKey constructor
- jclass clazzRSAPublicKey =
- env->FindClass("sun/security/mscapi/RSAPublicKey");
- if (clazzRSAPublicKey == NULL) {
+ // Get the method ID for the CPublicKey constructor
+ jclass clazzCPublicKey =
+ env->FindClass("sun/security/mscapi/CPublicKey");
+ if (clazzCPublicKey == NULL) {
__leave;
}
- jmethodID mNewRSAPublicKey =
- env->GetMethodID(clazzRSAPublicKey, "<init>", "(JJI)V");
- if (mNewRSAPublicKey == NULL) {
+ jmethodID mNewCPublicKey =
+ env->GetStaticMethodID(clazzCPublicKey, "of",
+ "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPublicKey;");
+ if (mNewCPublicKey == NULL) {
__leave;
}
- // Create a new RSA public key
- publicKey = env->NewObject(clazzRSAPublicKey, mNewRSAPublicKey,
- (jlong) hCryptProv, (jlong) hKey, keySize);
+ // Create a new public key
+ publicKey = env->CallStaticObjectMethod(clazzCPublicKey, mNewCPublicKey,
+ alg, (jlong) hCryptProv, (jlong) hKey, keySize);
}
__finally
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/mscapi/KeyAlgorithms.java Thu Dec 13 17:28:19 2018 +0800
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8213009
+ * @summary Make sure SunMSCAPI keys have correct algorithm names
+ * @requires os.family == "windows"
+ * @library /test/lib
+ * @modules jdk.crypto.mscapi
+ */
+
+import java.security.*;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.SecurityTools;
+
+public class KeyAlgorithms {
+
+ private static final String ALIAS = "8213009";
+ private static final String ALG = "RSA";
+
+ public static void main(String[] arg) throws Exception {
+
+ SecurityTools.keytool("-genkeypair",
+ "-storetype", "Windows-My",
+ "-keyalg", ALG,
+ "-alias", ALIAS,
+ "-dname", "cn=" + ALIAS,
+ "-noprompt").shouldHaveExitValue(0);
+
+ try {
+ test(loadKeysFromKeyStore());
+ } finally {
+ KeyStore ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+ ks.deleteEntry(ALIAS);
+ ks.store(null, null);
+ }
+
+ test(generateKeys());
+ }
+
+ static KeyPair loadKeysFromKeyStore() throws Exception {
+ KeyStore ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+ return new KeyPair(ks.getCertificate(ALIAS).getPublicKey(),
+ (PrivateKey) ks.getKey(ALIAS, null));
+ }
+
+ static KeyPair generateKeys() throws Exception {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALG, "SunMSCAPI");
+ return kpg.generateKeyPair();
+ }
+
+ static void test(KeyPair kp) {
+ Asserts.assertEQ(kp.getPrivate().getAlgorithm(), ALG);
+ Asserts.assertEQ(kp.getPublic().getAlgorithm(), ALG);
+ }
+}