8213009: Refactoring existing SunMSCAPI classes

Reviewed-by: valeriep
This commit is contained in:
Weijun Wang 2018-12-13 17:28:19 +08:00
parent eed637f497
commit dcb88767a7
15 changed files with 968 additions and 1036 deletions

View file

@ -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);
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2016, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,27 +30,22 @@ package sun.security.mscapi;
* *
* @since 1.6 * @since 1.6
*/ */
class RSAKeyPair { class CKeyPair {
private final RSAPrivateKey privateKey; private final CPrivateKey privateKey;
private final RSAPublicKey publicKey; private final CPublicKey publicKey;
/** CKeyPair(String alg, long hCryptProv, long hCryptKey, int keyLength) {
* Construct an RSAKeyPair object. privateKey = CPrivateKey.of(alg, hCryptProv, hCryptKey, keyLength);
*/ publicKey = CPublicKey.of(alg, hCryptProv, hCryptKey, keyLength);
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() { public CPrivateKey getPrivate() {
return privateKey; return privateKey;
} }
public RSAPublicKey getPublic() { public CPublicKey getPublic() {
return publicKey; return publicKey;
} }
} }

View file

@ -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;
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2017, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.AccessController; import java.security.AccessController;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyStoreSpi; import java.security.KeyStoreSpi;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
@ -49,31 +50,30 @@ import java.util.*;
* *
* @since 1.6 * @since 1.6
*/ */
abstract class KeyStore extends KeyStoreSpi { abstract class CKeyStore extends KeyStoreSpi {
public static final class MY extends KeyStore { public static final class MY extends CKeyStore {
public MY() { public MY() {
super("MY"); super("MY");
} }
} }
public static final class ROOT extends KeyStore { public static final class ROOT extends CKeyStore {
public ROOT() { public ROOT() {
super("ROOT"); super("ROOT");
} }
} }
class KeyEntry class KeyEntry {
{ private CKey privateKey;
private Key privateKey;
private X509Certificate[] certChain; private X509Certificate[] certChain;
private String alias; private String alias;
KeyEntry(Key key, X509Certificate[] chain) { KeyEntry(CKey key, X509Certificate[] chain) {
this(null, key, chain); this(null, key, chain);
} }
KeyEntry(String alias, Key key, X509Certificate[] chain) { KeyEntry(String alias, CKey key, X509Certificate[] chain) {
this.privateKey = key; this.privateKey = key;
this.certChain = chain; this.certChain = chain;
/* /*
@ -90,16 +90,14 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Gets the alias for the keystore entry. * Gets the alias for the keystore entry.
*/ */
String getAlias() String getAlias() {
{
return alias; return alias;
} }
/** /**
* Sets the alias for the keystore entry. * Sets the alias for the keystore entry.
*/ */
void setAlias(String alias) void setAlias(String alias) {
{
// TODO - set friendly name prop in cert store // TODO - set friendly name prop in cert store
this.alias = alias; this.alias = alias;
} }
@ -107,44 +105,42 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Gets the private key for the keystore entry. * Gets the private key for the keystore entry.
*/ */
Key getPrivateKey() CKey getPrivateKey() {
{
return privateKey; return privateKey;
} }
/** /**
* Sets the private key for the keystore entry. * Sets the private key for the keystore entry.
*/ */
void setPrivateKey(RSAPrivateCrtKey key) void setRSAPrivateKey(Key k)
throws InvalidKeyException, KeyStoreException throws InvalidKeyException, KeyStoreException {
{ RSAPrivateCrtKey key = (RSAPrivateCrtKey) k;
byte[] modulusBytes = key.getModulus().toByteArray(); byte[] modulusBytes = key.getModulus().toByteArray();
// Adjust key length due to sign bit // Adjust key length due to sign bit
int keyBitLength = (modulusBytes[0] == 0) int keyBitLength = (modulusBytes[0] == 0)
? (modulusBytes.length - 1) * 8 ? (modulusBytes.length - 1) * 8
: modulusBytes.length * 8; : modulusBytes.length * 8;
byte[] keyBlob = generatePrivateKeyBlob( byte[] keyBlob = generateRSAPrivateKeyBlob(
keyBitLength, keyBitLength,
modulusBytes, modulusBytes,
key.getPublicExponent().toByteArray(), key.getPublicExponent().toByteArray(),
key.getPrivateExponent().toByteArray(), key.getPrivateExponent().toByteArray(),
key.getPrimeP().toByteArray(), key.getPrimeP().toByteArray(),
key.getPrimeQ().toByteArray(), key.getPrimeQ().toByteArray(),
key.getPrimeExponentP().toByteArray(), key.getPrimeExponentP().toByteArray(),
key.getPrimeExponentQ().toByteArray(), key.getPrimeExponentQ().toByteArray(),
key.getCrtCoefficient().toByteArray()); key.getCrtCoefficient().toByteArray());
privateKey = storePrivateKey(Objects.requireNonNull(keyBlob), privateKey = storePrivateKey("RSA", Objects.requireNonNull(keyBlob),
"{" + UUID.randomUUID().toString() + "}", keyBitLength); "{" + UUID.randomUUID().toString() + "}", keyBitLength);
} }
/** /**
* Gets the certificate chain for the keystore entry. * Gets the certificate chain for the keystore entry.
*/ */
X509Certificate[] getCertificateChain() X509Certificate[] getCertificateChain() {
{
return certChain; return certChain;
} }
@ -152,8 +148,7 @@ abstract class KeyStore extends KeyStoreSpi {
* Sets the certificate chain for the keystore entry. * Sets the certificate chain for the keystore entry.
*/ */
void setCertificateChain(X509Certificate[] chain) void setCertificateChain(X509Certificate[] chain)
throws CertificateException, KeyStoreException throws CertificateException, KeyStoreException {
{
for (int i = 0; i < chain.length; i++) { for (int i = 0; i < chain.length; i++) {
byte[] encoding = chain[i].getEncoded(); byte[] encoding = chain[i].getEncoded();
if (i == 0 && privateKey != null) { if (i == 0 && privateKey != null) {
@ -199,7 +194,7 @@ abstract class KeyStore extends KeyStoreSpi {
*/ */
private final String storeName; private final String storeName;
KeyStore(String storeName) { CKeyStore(String storeName) {
// Get the compatibility mode // Get the compatibility mode
String prop = AccessController.doPrivileged( String prop = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP)); (PrivilegedAction<String>) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP));
@ -237,8 +232,7 @@ abstract class KeyStore extends KeyStoreSpi {
* @exception UnrecoverableKeyException if the key cannot be recovered. * @exception UnrecoverableKeyException if the key cannot be recovered.
*/ */
public java.security.Key engineGetKey(String alias, char[] password) public java.security.Key engineGetKey(String alias, char[] password)
throws NoSuchAlgorithmException, UnrecoverableKeyException throws NoSuchAlgorithmException, UnrecoverableKeyException {
{
if (alias == null) { if (alias == null) {
return null; return null;
} }
@ -267,8 +261,7 @@ abstract class KeyStore extends KeyStoreSpi {
* alias identifies either a <i>trusted certificate entry</i> or a * alias identifies either a <i>trusted certificate entry</i> or a
* <i>key entry</i> without a certificate chain). * <i>key entry</i> without a certificate chain).
*/ */
public Certificate[] engineGetCertificateChain(String alias) public Certificate[] engineGetCertificateChain(String alias) {
{
if (alias == null) { if (alias == null) {
return null; return null;
} }
@ -297,8 +290,7 @@ abstract class KeyStore extends KeyStoreSpi {
* @return the certificate, or null if the given alias does not exist or * @return the certificate, or null if the given alias does not exist or
* does not contain a certificate. * does not contain a certificate.
*/ */
public Certificate engineGetCertificate(String alias) public Certificate engineGetCertificate(String alias) {
{
if (alias == null) { if (alias == null) {
return null; return null;
} }
@ -361,8 +353,7 @@ abstract class KeyStore extends KeyStoreSpi {
* some other reason. * some other reason.
*/ */
public void engineSetKeyEntry(String alias, java.security.Key key, public void engineSetKeyEntry(String alias, java.security.Key key,
char[] password, Certificate[] chain) throws KeyStoreException char[] password, Certificate[] chain) throws KeyStoreException {
{
if (alias == null) { if (alias == null) {
throw new KeyStoreException("alias must not be null"); throw new KeyStoreException("alias must not be null");
} }
@ -397,7 +388,7 @@ abstract class KeyStore extends KeyStoreSpi {
entry.setAlias(alias); entry.setAlias(alias);
try { try {
entry.setPrivateKey((RSAPrivateCrtKey) key); entry.setRSAPrivateKey(key);
entry.setCertificateChain(xchain); entry.setCertificateChain(xchain);
} catch (CertificateException ce) { } catch (CertificateException ce) {
@ -438,8 +429,7 @@ abstract class KeyStore extends KeyStoreSpi {
*/ */
public void engineSetKeyEntry(String alias, byte[] key, public void engineSetKeyEntry(String alias, byte[] key,
Certificate[] chain) Certificate[] chain)
throws KeyStoreException throws KeyStoreException {
{
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"Cannot assign the encoded key to the given alias."); "Cannot assign the encoded key to the given alias.");
} }
@ -459,8 +449,7 @@ abstract class KeyStore extends KeyStoreSpi {
* fails for some other reason. * fails for some other reason.
*/ */
public void engineSetCertificateEntry(String alias, Certificate cert) public void engineSetCertificateEntry(String alias, Certificate cert)
throws KeyStoreException throws KeyStoreException {
{
if (alias == null) { if (alias == null) {
throw new KeyStoreException("alias must not be null"); throw new KeyStoreException("alias must not be null");
} }
@ -502,9 +491,7 @@ abstract class KeyStore extends KeyStoreSpi {
* *
* @exception KeyStoreException if the entry cannot be removed. * @exception KeyStoreException if the entry cannot be removed.
*/ */
public void engineDeleteEntry(String alias) public void engineDeleteEntry(String alias) throws KeyStoreException {
throws KeyStoreException
{
if (alias == null) { if (alias == null) {
throw new KeyStoreException("alias must not be null"); throw new KeyStoreException("alias must not be null");
} }
@ -525,10 +512,10 @@ abstract class KeyStore extends KeyStoreSpi {
throw new KeyStoreException("Cannot remove entry: ", e); throw new KeyStoreException("Cannot remove entry: ", e);
} }
} }
Key privateKey = entry.getPrivateKey(); CKey privateKey = entry.getPrivateKey();
if (privateKey != null) { if (privateKey != null) {
destroyKeyContainer( destroyKeyContainer(
Key.getContainerName(privateKey.getHCryptProvider())); CKey.getContainerName(privateKey.getHCryptProvider()));
} }
} }
} }
@ -541,15 +528,12 @@ abstract class KeyStore extends KeyStoreSpi {
public Enumeration<String> engineAliases() { public Enumeration<String> engineAliases() {
final Iterator<String> iter = entries.keySet().iterator(); final Iterator<String> iter = entries.keySet().iterator();
return new Enumeration<String>() return new Enumeration<String>() {
{ public boolean hasMoreElements() {
public boolean hasMoreElements()
{
return iter.hasNext(); return iter.hasNext();
} }
public String nextElement() public String nextElement() {
{
return iter.next(); return iter.next();
} }
}; };
@ -659,8 +643,7 @@ abstract class KeyStore extends KeyStoreSpi {
* parameter is non-null. * parameter is non-null.
*/ */
public void engineStore(OutputStream stream, char[] password) public void engineStore(OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException throws IOException, NoSuchAlgorithmException, CertificateException {
{
if (stream != null && !keyStoreCompatibilityMode) { if (stream != null && !keyStoreCompatibilityMode) {
throw new IOException("Keystore output stream must be null"); throw new IOException("Keystore output stream must be null");
} }
@ -698,8 +681,7 @@ abstract class KeyStore extends KeyStoreSpi {
* this provider's <code>getName</code> method. * this provider's <code>getName</code> method.
*/ */
public void engineLoad(InputStream stream, char[] password) public void engineLoad(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException throws IOException, NoSuchAlgorithmException, CertificateException {
{
if (stream != null && !keyStoreCompatibilityMode) { if (stream != null && !keyStoreCompatibilityMode) {
throw new IOException("Keystore input stream must be null"); throw new IOException("Keystore input stream must be null");
} }
@ -753,27 +735,24 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Generates a certificate chain from the collection of * Generates a certificate chain from the collection of
* certificates and stores the result into a key entry. * 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, private void generateCertificateChain(String alias,
Collection<? extends Certificate> certCollection) Collection<? extends Certificate> certCollection) {
{ try {
try
{
X509Certificate[] certChain = X509Certificate[] certChain =
new X509Certificate[certCollection.size()]; new X509Certificate[certCollection.size()];
int i = 0; int i = 0;
for (Iterator<? extends Certificate> iter = for (Iterator<? extends Certificate> iter =
certCollection.iterator(); iter.hasNext(); i++) certCollection.iterator(); iter.hasNext(); i++) {
{
certChain[i] = (X509Certificate) iter.next(); certChain[i] = (X509Certificate) iter.next();
} }
storeWithUniqueAlias(alias, storeWithUniqueAlias(alias,
new KeyEntry(alias, null, certChain)); new KeyEntry(alias, null, certChain));
} } catch (Throwable e) {
catch (Throwable e)
{
// Ignore the exception and skip this entry // Ignore the exception and skip this entry
// TODO - throw CertificateException? // TODO - throw CertificateException?
} }
@ -782,30 +761,25 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Generates RSA key and certificate chain from the private key handle, * Generates RSA key and certificate chain from the private key handle,
* collection of certificates and stores the result into key entries. * 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, private void generateRSAKeyAndCertificateChain(String alias,
long hCryptProv, long hCryptKey, int keyLength, long hCryptProv, long hCryptKey, int keyLength,
Collection<? extends Certificate> certCollection) Collection<? extends Certificate> certCollection) {
{ try {
try
{
X509Certificate[] certChain = X509Certificate[] certChain =
new X509Certificate[certCollection.size()]; new X509Certificate[certCollection.size()];
int i = 0; int i = 0;
for (Iterator<? extends Certificate> iter = for (Iterator<? extends Certificate> iter =
certCollection.iterator(); iter.hasNext(); i++) certCollection.iterator(); iter.hasNext(); i++) {
{
certChain[i] = (X509Certificate) iter.next(); certChain[i] = (X509Certificate) iter.next();
} }
storeWithUniqueAlias(alias, new KeyEntry(alias, storeWithUniqueAlias(alias, new KeyEntry(alias,
new RSAPrivateKey(new Key.NativeHandles(hCryptProv, CPrivateKey.of("RSA", hCryptProv, hCryptKey, keyLength),
hCryptKey), keyLength),
certChain)); certChain));
} } catch (Throwable e) {
catch (Throwable e)
{
// Ignore the exception and skip this entry // Ignore the exception and skip this entry
// TODO - throw CertificateException? // TODO - throw CertificateException?
} }
@ -813,14 +787,15 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Generates certificates from byte data and stores into cert collection. * 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 data Byte data.
* @param certCollection Collection of certificates. * @param certCollection Collection of certificates.
*/ */
private void generateCertificate(byte[] data, private void generateCertificate(byte[] data,
Collection<Certificate> certCollection) { Collection<Certificate> certCollection) {
try try {
{
ByteArrayInputStream bis = new ByteArrayInputStream(data); ByteArrayInputStream bis = new ByteArrayInputStream(data);
// Obtain certificate factory // Obtain certificate factory
@ -832,14 +807,10 @@ abstract class KeyStore extends KeyStoreSpi {
Collection<? extends Certificate> c = Collection<? extends Certificate> c =
certificateFactory.generateCertificates(bis); certificateFactory.generateCertificates(bis);
certCollection.addAll(c); certCollection.addAll(c);
} } catch (CertificateException e) {
catch (CertificateException e)
{
// Ignore the exception and skip this certificate // Ignore the exception and skip this certificate
// TODO - throw CertificateException? // TODO - throw CertificateException?
} } catch (Throwable te) {
catch (Throwable te)
{
// Ignore the exception and skip this certificate // Ignore the exception and skip this certificate
// TODO - throw CertificateException? // TODO - throw CertificateException?
} }
@ -848,8 +819,7 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Returns the name of the keystore. * Returns the name of the keystore.
*/ */
private String getName() private String getName() {
{
return storeName; return storeName;
} }
@ -894,7 +864,7 @@ abstract class KeyStore extends KeyStoreSpi {
/** /**
* Generates a private-key BLOB from a key's components. * Generates a private-key BLOB from a key's components.
*/ */
private native byte[] generatePrivateKeyBlob( private native byte[] generateRSAPrivateKeyBlob(
int keyBitLength, int keyBitLength,
byte[] modulus, byte[] modulus,
byte[] publicExponent, byte[] publicExponent,
@ -905,6 +875,6 @@ abstract class KeyStore extends KeyStoreSpi {
byte[] exponentQ, byte[] exponentQ,
byte[] crtCoefficient) throws InvalidKeyException; byte[] crtCoefficient) throws InvalidKeyException;
private native RSAPrivateKey storePrivateKey(byte[] keyBlob, private native CPrivateKey storePrivateKey(String alg, byte[] keyBlob,
String keyContainerName, int keySize) throws KeyStoreException; String keyContainerName, int keySize) throws KeyStoreException;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2016, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,57 +28,42 @@ package sun.security.mscapi;
import java.security.PrivateKey; import java.security.PrivateKey;
/** /**
* The handle for an RSA private key using the Microsoft Crypto API. * The handle for a private key using the Microsoft Crypto API.
* *
* @author Stanley Man-Kit Ho * @author Stanley Man-Kit Ho
* @since 1.6 * @since 1.6
*/ */
class RSAPrivateKey extends Key implements PrivateKey class CPrivateKey extends CKey implements PrivateKey {
{
private static final long serialVersionUID = 8113152807912338063L; private static final long serialVersionUID = 8113152807912338063L;
/** private CPrivateKey(String alg, long hCryptProv, long hCryptKey, int keyLength) {
* Construct an RSAPrivateKey object. super(alg, hCryptProv, hCryptKey, keyLength);
*/
RSAPrivateKey(long hCryptProv, long hCryptKey, int keyLength)
{
super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
} }
/** public static CPrivateKey of(String alg, long hCryptProv, long hCryptKey, int keyLength) {
* Construct an RSAPrivateKey object. return new CPrivateKey(alg, hCryptProv, hCryptKey, keyLength);
*/
RSAPrivateKey(NativeHandles handles, int keyLength)
{
super(handles, keyLength);
} }
/** // this key does not support encoding
* Returns the standard algorithm name for this key. For public String getFormat() {
* example, "RSA" would indicate that this key is a RSA key. return null;
* See Appendix A in the <a href=
* "../../../guide/security/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; 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() // this key does not support encoding
{ public byte[] getEncoded() {
return "RSAPrivateKey [size=" + keyLength + " bits, type=" + return null;
}
public String toString() {
return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" +
getKeyType(handles.hCryptKey) + ", container=" + getKeyType(handles.hCryptKey) + ", container=" +
getContainerName(handles.hCryptProv) + "]"; getContainerName(handles.hCryptProv) + "]";
} }
// This class is not serializable // This class is not serializable
private void writeObject(java.io.ObjectOutputStream out) private void writeObject(java.io.ObjectOutputStream out)
throws java.io.IOException { throws java.io.IOException {
throw new java.io.NotSerializableException(); throw new java.io.NotSerializableException();
} }
} }

View file

@ -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;
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,7 +39,7 @@ import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
import sun.security.util.KeyUtil; import sun.security.util.KeyUtil;
/** /**
* RSA cipher implementation using the Microsoft Crypto API. * Cipher implementation using the Microsoft Crypto API.
* Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding. * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
* *
* Objects should be instantiated by calling Cipher.getInstance() using the * Objects should be instantiated by calling Cipher.getInstance() using the
@ -59,7 +59,7 @@ import sun.security.util.KeyUtil;
* @author Andreas Sterbenz * @author Andreas Sterbenz
* @author Vincent Ryan * @author Vincent Ryan
*/ */
public final class RSACipher extends CipherSpi { public final class CRSACipher extends CipherSpi {
// constant for an empty byte array // constant for an empty byte array
private final static byte[] B0 = new byte[0]; private final static byte[] B0 = new byte[0];
@ -93,10 +93,10 @@ public final class RSACipher extends CipherSpi {
private int outputSize; private int outputSize;
// the public key, if we were initialized using a public key // the public key, if we were initialized using a public key
private sun.security.mscapi.Key publicKey; private CKey publicKey;
// the private key, if we were initialized using a private key // the private key, if we were initialized using a private key
private sun.security.mscapi.Key privateKey; private CKey privateKey;
// cipher parameter for TLS RSA premaster secret // cipher parameter for TLS RSA premaster secret
private AlgorithmParameterSpec spec = null; private AlgorithmParameterSpec spec = null;
@ -104,7 +104,7 @@ public final class RSACipher extends CipherSpi {
// the source of randomness // the source of randomness
private SecureRandom random; private SecureRandom random;
public RSACipher() { public CRSACipher() {
paddingType = PAD_PKCS1; paddingType = PAD_PKCS1;
} }
@ -207,7 +207,7 @@ public final class RSACipher extends CipherSpi {
throw new InvalidKeyException("Unknown mode: " + opmode); throw new InvalidKeyException("Unknown mode: " + opmode);
} }
if (!(key instanceof sun.security.mscapi.Key)) { if (!(key instanceof CKey)) {
if (key instanceof java.security.interfaces.RSAPublicKey) { if (key instanceof java.security.interfaces.RSAPublicKey) {
java.security.interfaces.RSAPublicKey rsaKey = java.security.interfaces.RSAPublicKey rsaKey =
(java.security.interfaces.RSAPublicKey) key; (java.security.interfaces.RSAPublicKey) key;
@ -220,7 +220,7 @@ public final class RSACipher extends CipherSpi {
// Check against the local and global values to make sure // Check against the local and global values to make sure
// the sizes are ok. Round up to the nearest byte. // the sizes are ok. Round up to the nearest byte.
RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7), RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX); exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);
byte[] modulusBytes = modulus.toByteArray(); byte[] modulusBytes = modulus.toByteArray();
byte[] exponentBytes = exponent.toByteArray(); byte[] exponentBytes = exponent.toByteArray();
@ -230,11 +230,11 @@ public final class RSACipher extends CipherSpi {
? (modulusBytes.length - 1) * 8 ? (modulusBytes.length - 1) * 8
: modulusBytes.length * 8; : modulusBytes.length * 8;
byte[] keyBlob = RSASignature.generatePublicKeyBlob( byte[] keyBlob = CSignature.RSA.generatePublicKeyBlob(
keyBitLength, modulusBytes, exponentBytes); keyBitLength, modulusBytes, exponentBytes);
try { try {
key = RSASignature.importPublicKey(keyBlob, keyBitLength); key = CSignature.importPublicKey("RSA", keyBlob, keyBitLength);
} catch (KeyStoreException e) { } catch (KeyStoreException e) {
throw new InvalidKeyException(e); throw new InvalidKeyException(e);
@ -247,12 +247,12 @@ public final class RSACipher extends CipherSpi {
if (key instanceof PublicKey) { if (key instanceof PublicKey) {
mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY; mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
publicKey = (sun.security.mscapi.Key)key; publicKey = (CKey)key;
privateKey = null; privateKey = null;
outputSize = publicKey.length() / 8; outputSize = publicKey.length() / 8;
} else if (key instanceof PrivateKey) { } else if (key instanceof PrivateKey) {
mode = encrypt ? MODE_SIGN : MODE_DECRYPT; mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
privateKey = (sun.security.mscapi.Key)key; privateKey = (CKey)key;
publicKey = null; publicKey = null;
outputSize = privateKey.length() / 8; outputSize = privateKey.length() / 8;
} else { } else {
@ -417,8 +417,8 @@ public final class RSACipher extends CipherSpi {
// see JCE spec // see JCE spec
protected int engineGetKeySize(Key key) throws InvalidKeyException { protected int engineGetKeySize(Key key) throws InvalidKeyException {
if (key instanceof sun.security.mscapi.Key) { if (key instanceof CKey) {
return ((sun.security.mscapi.Key) key).length(); return ((CKey) key).length();
} else if (key instanceof RSAKey) { } else if (key instanceof RSAKey) {
return ((RSAKey) key).getModulus().bitLength(); return ((RSAKey) key).getModulus().bitLength();

View file

@ -27,6 +27,7 @@ package sun.security.mscapi;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.*; import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.spec.MGF1ParameterSpec; import java.security.spec.MGF1ParameterSpec;
@ -36,7 +37,8 @@ import java.util.Locale;
import sun.security.rsa.RSAKeyFactory; import sun.security.rsa.RSAKeyFactory;
/** /**
* RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding. * 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 * Objects should be instantiated by calling Signature.getInstance() using the
* following algorithm names: * following algorithm names:
@ -60,50 +62,185 @@ import sun.security.rsa.RSAKeyFactory;
* @since 1.6 * @since 1.6
* @author Stanley Man-Kit Ho * @author Stanley Man-Kit Ho
*/ */
abstract class RSASignature extends java.security.SignatureSpi abstract class CSignature extends SignatureSpi {
{ // private key algorithm name
protected String keyAlgorithm;
// message digest implementation we use // message digest implementation we use
protected MessageDigest messageDigest; protected MessageDigest messageDigest;
// message digest name // message digest name
private String messageDigestAlgorithm; protected String messageDigestAlgorithm;
// flag indicating whether the digest has been reset // flag indicating whether the digest has been reset
protected boolean needsReset; protected boolean needsReset;
// the signing key // the signing key
protected Key privateKey = null; protected CPrivateKey privateKey = null;
// the verification key // the verification key
protected Key publicKey = null; protected CPublicKey publicKey = null;
/** /**
* Constructs a new RSASignature. Used by Raw subclass. * Constructs a new CSignature. Used by subclasses.
*/ */
RSASignature() { CSignature(String keyName, String digestName) {
messageDigest = null;
messageDigestAlgorithm = null;
}
/** this.keyAlgorithm = keyName;
* Constructs a new RSASignature. Used by subclasses. if (digestName != null) {
*/ try {
RSASignature(String digestName) { messageDigest = MessageDigest.getInstance(digestName);
// Get the digest's canonical name
try { messageDigestAlgorithm = messageDigest.getAlgorithm();
messageDigest = MessageDigest.getInstance(digestName); } catch (NoSuchAlgorithmException e) {
// Get the digest's canonical name throw new ProviderException(e);
messageDigestAlgorithm = messageDigest.getAlgorithm(); }
} else {
} catch (NoSuchAlgorithmException e) { messageDigest = null;
throw new ProviderException(e); messageDigestAlgorithm = null;
} }
needsReset = false; 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 // Nested class for NONEwithRSA signatures
public static final class Raw extends RSASignature { public static final class NONEwithRSA extends RSA {
// the longest supported digest is 512 bits (SHA-512) // the longest supported digest is 512 bits (SHA-512)
private static final int RAW_RSA_MAX = 64; private static final int RAW_RSA_MAX = 64;
@ -111,7 +248,8 @@ abstract class RSASignature extends java.security.SignatureSpi
private final byte[] precomputedDigest; private final byte[] precomputedDigest;
private int offset = 0; private int offset = 0;
public Raw() { public NONEwithRSA() {
super(null);
precomputedDigest = new byte[RAW_RSA_MAX]; precomputedDigest = new byte[RAW_RSA_MAX];
} }
@ -190,43 +328,43 @@ abstract class RSASignature extends java.security.SignatureSpi
} }
} }
public static final class SHA1 extends RSASignature { public static final class SHA1withRSA extends RSA {
public SHA1() { public SHA1withRSA() {
super("SHA1"); super("SHA1");
} }
} }
public static final class SHA256 extends RSASignature { public static final class SHA256withRSA extends RSA {
public SHA256() { public SHA256withRSA() {
super("SHA-256"); super("SHA-256");
} }
} }
public static final class SHA384 extends RSASignature { public static final class SHA384withRSA extends RSA {
public SHA384() { public SHA384withRSA() {
super("SHA-384"); super("SHA-384");
} }
} }
public static final class SHA512 extends RSASignature { public static final class SHA512withRSA extends RSA {
public SHA512() { public SHA512withRSA() {
super("SHA-512"); super("SHA-512");
} }
} }
public static final class MD5 extends RSASignature { public static final class MD5withRSA extends RSA {
public MD5() { public MD5withRSA() {
super("MD5"); super("MD5");
} }
} }
public static final class MD2 extends RSASignature { public static final class MD2withRSA extends RSA {
public MD2() { public MD2withRSA() {
super("MD2"); super("MD2");
} }
} }
public static final class PSS extends RSASignature { public static final class PSS extends RSA {
private PSSParameterSpec pssParams = null; private PSSParameterSpec pssParams = null;
@ -234,6 +372,10 @@ abstract class RSASignature extends java.security.SignatureSpi
// will be used for verification if key is not from MSCAPI. // will be used for verification if key is not from MSCAPI.
private Signature fallbackSignature; private Signature fallbackSignature;
public PSS() {
super(null);
}
@Override @Override
protected void engineInitSign(PrivateKey key) throws InvalidKeyException { protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
super.engineInitSign(key); super.engineInitSign(key);
@ -249,9 +391,9 @@ abstract class RSASignature extends java.security.SignatureSpi
this.privateKey = null; this.privateKey = null;
if (key instanceof sun.security.mscapi.RSAPublicKey) { if (key instanceof CPublicKey) {
fallbackSignature = null; fallbackSignature = null;
publicKey = (sun.security.mscapi.RSAPublicKey) key; publicKey = (CPublicKey) key;
} else { } else {
if (fallbackSignature == null) { if (fallbackSignature == null) {
try { try {
@ -321,7 +463,7 @@ abstract class RSASignature extends java.security.SignatureSpi
protected byte[] engineSign() throws SignatureException { protected byte[] engineSign() throws SignatureException {
ensureInit(); ensureInit();
byte[] hash = getDigestValue(); byte[] hash = getDigestValue();
return signPssHash(hash, hash.length, return signCngHash(hash, hash.length,
pssParams.getSaltLength(), pssParams.getSaltLength(),
((MGF1ParameterSpec) ((MGF1ParameterSpec)
pssParams.getMGFParameters()).getDigestAlgorithm(), pssParams.getMGFParameters()).getDigestAlgorithm(),
@ -336,7 +478,7 @@ abstract class RSASignature extends java.security.SignatureSpi
return fallbackSignature.verify(sigBytes); return fallbackSignature.verify(sigBytes);
} else { } else {
byte[] hash = getDigestValue(); byte[] hash = getDigestValue();
return verifyPssSignedHash( return verifyCngSignedHash(
hash, hash.length, hash, hash.length,
sigBytes, sigBytes.length, sigBytes, sigBytes.length,
pssParams.getSaltLength(), pssParams.getSaltLength(),
@ -454,95 +596,24 @@ abstract class RSASignature extends java.security.SignatureSpi
return params; 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 * Sign hash using CNG API with HCRYPTKEY. Used by RSASSA-PSS.
protected void engineInitVerify(PublicKey key) */
throws InvalidKeyException native static byte[] signCngHash(
{ byte[] hash, int hashSize, int saltLength, String hashAlgorithm,
// This signature accepts only RSAPublicKey long hCryptProv, long nCryptKey)
if ((key instanceof java.security.interfaces.RSAPublicKey) == false) { throws SignatureException;
throw new InvalidKeyException("Key type not supported");
}
java.security.interfaces.RSAPublicKey rsaKey = /**
(java.security.interfaces.RSAPublicKey) key; * Verify a signed hash using CNG API with HCRYPTKEY. Used by RSASSA-PSS.
* This method is not used now. See {@link PSS#fallbackSignature}.
if ((key instanceof sun.security.mscapi.RSAPublicKey) == false) { */
private native static boolean verifyCngSignedHash(
// convert key to MSCAPI format byte[] hash, int hashSize, byte[] signature, int signatureSize,
int saltLength, String hashAlgorithm,
BigInteger modulus = rsaKey.getModulus(); long hCryptProv, long hKey) throws SignatureException;
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. * Resets the message digest if needed.
@ -575,8 +646,7 @@ abstract class RSASignature extends java.security.SignatureSpi
* properly. * properly.
*/ */
@Override @Override
protected void engineUpdate(byte b) throws SignatureException protected void engineUpdate(byte b) throws SignatureException {
{
messageDigest.update(b); messageDigest.update(b);
needsReset = true; needsReset = true;
} }
@ -594,8 +664,7 @@ abstract class RSASignature extends java.security.SignatureSpi
*/ */
@Override @Override
protected void engineUpdate(byte[] b, int off, int len) protected void engineUpdate(byte[] b, int off, int len)
throws SignatureException throws SignatureException {
{
messageDigest.update(b, off, len); messageDigest.update(b, off, len);
needsReset = true; needsReset = true;
} }
@ -607,47 +676,15 @@ abstract class RSASignature extends java.security.SignatureSpi
* @param input the ByteBuffer * @param input the ByteBuffer
*/ */
@Override @Override
protected void engineUpdate(ByteBuffer input) protected void engineUpdate(ByteBuffer input) {
{
messageDigest.update(input); messageDigest.update(input);
needsReset = true; 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. * Convert array from big endian to little endian, or vice versa.
*/ */
private byte[] convertEndianArray(byte[] byteArray) private static byte[] convertEndianArray(byte[] byteArray) {
{
if (byteArray == null || byteArray.length == 0) if (byteArray == null || byteArray.length == 0)
return byteArray; return byteArray;
@ -675,30 +712,6 @@ abstract class RSASignature extends java.security.SignatureSpi
String hashAlgorithm, byte[] signature, int signatureSize, String hashAlgorithm, byte[] signature, int signatureSize,
long hCryptProv, long hCryptKey) throws SignatureException; 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 * Sets the specified algorithm parameter to the specified
* value. This method supplies a general-purpose mechanism through * value. This method supplies a general-purpose mechanism through
@ -726,8 +739,7 @@ abstract class RSASignature extends java.security.SignatureSpi
@Override @Override
@Deprecated @Deprecated
protected void engineSetParameter(String param, Object value) protected void engineSetParameter(String param, Object value)
throws InvalidParameterException throws InvalidParameterException {
{
throw new InvalidParameterException("Parameter not supported"); throw new InvalidParameterException("Parameter not supported");
} }
@ -741,8 +753,7 @@ abstract class RSASignature extends java.security.SignatureSpi
*/ */
@Override @Override
protected void engineSetParameter(AlgorithmParameterSpec params) protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException throws InvalidAlgorithmParameterException {
{
if (params != null) { if (params != null) {
throw new InvalidAlgorithmParameterException("No parameter accepted"); throw new InvalidAlgorithmParameterException("No parameter accepted");
} }
@ -773,8 +784,7 @@ abstract class RSASignature extends java.security.SignatureSpi
@Override @Override
@Deprecated @Deprecated
protected Object engineGetParameter(String param) protected Object engineGetParameter(String param)
throws InvalidParameterException throws InvalidParameterException {
{
throw new InvalidParameterException("Parameter not supported"); throw new InvalidParameterException("Parameter not supported");
} }
@ -788,18 +798,10 @@ abstract class RSASignature extends java.security.SignatureSpi
return null; 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. * Imports a public-key BLOB.
*/ */
// used by RSACipher // used by CRSACipher
static native RSAPublicKey importPublicKey(byte[] keyBlob, int keySize) static native CPublicKey importPublicKey(
throws KeyStoreException; String alg, byte[] keyBlob, int keySize) throws KeyStoreException;
} }

View file

@ -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 &amp; 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);
}

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View file

@ -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;
}

View file

@ -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 &amp; 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;
}

View file

@ -33,7 +33,6 @@ import java.security.InvalidParameterException;
import java.security.ProviderException; import java.security.ProviderException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import static sun.security.util.SecurityConstants.PROVIDER_VER; import static sun.security.util.SecurityConstants.PROVIDER_VER;
@ -86,36 +85,36 @@ public final class SunMSCAPI extends Provider {
} }
} else if (type.equals("KeyStore")) { } else if (type.equals("KeyStore")) {
if (algo.equals("Windows-MY")) { if (algo.equals("Windows-MY")) {
return new KeyStore.MY(); return new CKeyStore.MY();
} else if (algo.equals("Windows-ROOT")) { } else if (algo.equals("Windows-ROOT")) {
return new KeyStore.ROOT(); return new CKeyStore.ROOT();
} }
} else if (type.equals("Signature")) { } else if (type.equals("Signature")) {
if (algo.equals("NONEwithRSA")) { if (algo.equals("NONEwithRSA")) {
return new RSASignature.Raw(); return new CSignature.NONEwithRSA();
} else if (algo.equals("SHA1withRSA")) { } else if (algo.equals("SHA1withRSA")) {
return new RSASignature.SHA1(); return new CSignature.SHA1withRSA();
} else if (algo.equals("SHA256withRSA")) { } else if (algo.equals("SHA256withRSA")) {
return new RSASignature.SHA256(); return new CSignature.SHA256withRSA();
} else if (algo.equals("SHA384withRSA")) { } else if (algo.equals("SHA384withRSA")) {
return new RSASignature.SHA384(); return new CSignature.SHA384withRSA();
} else if (algo.equals("SHA512withRSA")) { } else if (algo.equals("SHA512withRSA")) {
return new RSASignature.SHA512(); return new CSignature.SHA512withRSA();
} else if (algo.equals("MD5withRSA")) { } else if (algo.equals("MD5withRSA")) {
return new RSASignature.MD5(); return new CSignature.MD5withRSA();
} else if (algo.equals("MD2withRSA")) { } else if (algo.equals("MD2withRSA")) {
return new RSASignature.MD2(); return new CSignature.MD2withRSA();
} else if (algo.equals("RSASSA-PSS")) { } else if (algo.equals("RSASSA-PSS")) {
return new RSASignature.PSS(); return new CSignature.PSS();
} }
} else if (type.equals("KeyPairGenerator")) { } else if (type.equals("KeyPairGenerator")) {
if (algo.equals("RSA")) { if (algo.equals("RSA")) {
return new RSAKeyPairGenerator(); return new CKeyPairGenerator.RSA();
} }
} else if (type.equals("Cipher")) { } else if (type.equals("Cipher")) {
if (algo.equals("RSA") || if (algo.equals("RSA") ||
algo.equals("RSA/ECB/PKCS1Padding")) { algo.equals("RSA/ECB/PKCS1Padding")) {
return new RSACipher(); return new CRSACipher();
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -147,47 +146,47 @@ public final class SunMSCAPI extends Provider {
* Key store * Key store
*/ */
putService(new ProviderService(p, "KeyStore", putService(new ProviderService(p, "KeyStore",
"Windows-MY", "sun.security.mscapi.KeyStore$MY")); "Windows-MY", "sun.security.mscapi.CKeyStore$MY"));
putService(new ProviderService(p, "KeyStore", putService(new ProviderService(p, "KeyStore",
"Windows-ROOT", "sun.security.mscapi.KeyStore$ROOT")); "Windows-ROOT", "sun.security.mscapi.CKeyStore$ROOT"));
/* /*
* Signature engines * Signature engines
*/ */
HashMap<String, String> attrs = new HashMap<>(1); 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. // NONEwithRSA must be supplied with a pre-computed message digest.
// Only the following digest algorithms are supported: MD5, SHA-1, // Only the following digest algorithms are supported: MD5, SHA-1,
// SHA-256, SHA-384, SHA-512 and a special-purpose digest // SHA-256, SHA-384, SHA-512 and a special-purpose digest
// algorithm which is a concatenation of SHA-1 and MD5 digests. // algorithm which is a concatenation of SHA-1 and MD5 digests.
putService(new ProviderService(p, "Signature", putService(new ProviderService(p, "Signature",
"NONEwithRSA", "sun.security.mscapi.RSASignature$Raw", "NONEwithRSA", "sun.security.mscapi.CSignature$NONEwithRSA",
null, attrs)); null, attrs));
putService(new ProviderService(p, "Signature", putService(new ProviderService(p, "Signature",
"SHA1withRSA", "sun.security.mscapi.RSASignature$SHA1", "SHA1withRSA", "sun.security.mscapi.CSignature$SHA1withRSA",
null, attrs)); null, attrs));
putService(new ProviderService(p, "Signature", 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" }, new String[] { "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11" },
attrs)); attrs));
putService(new ProviderService(p, "Signature", 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" }, new String[] { "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12" },
attrs)); attrs));
putService(new ProviderService(p, "Signature", 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" }, new String[] { "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13" },
attrs)); attrs));
putService(new ProviderService(p, "Signature", 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" }, new String[] { "1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10" },
attrs)); attrs));
putService(new ProviderService(p, "Signature", putService(new ProviderService(p, "Signature",
"MD5withRSA", "sun.security.mscapi.RSASignature$MD5", "MD5withRSA", "sun.security.mscapi.CSignature$MD5withRSA",
null, attrs)); null, attrs));
putService(new ProviderService(p, "Signature", putService(new ProviderService(p, "Signature",
"MD2withRSA", "sun.security.mscapi.RSASignature$MD2", "MD2withRSA", "sun.security.mscapi.CSignature$MD2withRSA",
null, attrs)); null, attrs));
/* /*
@ -196,7 +195,7 @@ public final class SunMSCAPI extends Provider {
attrs.clear(); attrs.clear();
attrs.put("KeySize", "16384"); attrs.put("KeySize", "16384");
putService(new ProviderService(p, "KeyPairGenerator", putService(new ProviderService(p, "KeyPairGenerator",
"RSA", "sun.security.mscapi.RSAKeyPairGenerator", "RSA", "sun.security.mscapi.CKeyPairGenerator$RSA",
null, attrs)); null, attrs));
/* /*
@ -205,12 +204,12 @@ public final class SunMSCAPI extends Provider {
attrs.clear(); attrs.clear();
attrs.put("SupportedModes", "ECB"); attrs.put("SupportedModes", "ECB");
attrs.put("SupportedPaddings", "PKCS1PADDING"); attrs.put("SupportedPaddings", "PKCS1PADDING");
attrs.put("SupportedKeyClasses", "sun.security.mscapi.Key"); attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey");
putService(new ProviderService(p, "Cipher", putService(new ProviderService(p, "Cipher",
"RSA", "sun.security.mscapi.RSACipher", "RSA", "sun.security.mscapi.CRSACipher",
null, attrs)); null, attrs));
putService(new ProviderService(p, "Cipher", putService(new ProviderService(p, "Cipher",
"RSA/ECB/PKCS1Padding", "sun.security.mscapi.RSACipher", "RSA/ECB/PKCS1Padding", "sun.security.mscapi.CRSACipher",
null, attrs)); null, attrs));
return null; return null;
} }

View file

@ -37,13 +37,15 @@
#include <wincrypt.h> #include <wincrypt.h>
#include <stdio.h> #include <stdio.h>
#include <memory> #include <memory>
#include "sun_security_mscapi_Key.h" #include "sun_security_mscapi_CKey.h"
#include "sun_security_mscapi_KeyStore.h" #include "sun_security_mscapi_CKeyStore.h"
#include "sun_security_mscapi_PRNG.h" #include "sun_security_mscapi_PRNG.h"
#include "sun_security_mscapi_RSACipher.h" #include "sun_security_mscapi_CRSACipher.h"
#include "sun_security_mscapi_RSAKeyPairGenerator.h" #include "sun_security_mscapi_CKeyPairGenerator_RSA.h"
#include "sun_security_mscapi_RSAPublicKey.h" #include "sun_security_mscapi_CPublicKey.h"
#include "sun_security_mscapi_RSASignature.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" #define OID_EKU_ANY "2.5.29.37.0"
@ -64,7 +66,7 @@
} }
//#define PP(fmt, ...) \ //#define PP(fmt, ...) \
// fprintf(stdout, "SSPI (%ld): ", __LINE__); \ // fprintf(stdout, "MSCAPI (%ld): ", __LINE__); \
// fprintf(stdout, fmt, ##__VA_ARGS__); \ // fprintf(stdout, fmt, ##__VA_ARGS__); \
// fprintf(stdout, "\n"); \ // fprintf(stdout, "\n"); \
// fflush(stdout) // fflush(stdout)
@ -79,13 +81,27 @@ DEF_STATIC_JNI_OnLoad
//void dump(LPSTR title, PBYTE data, DWORD len) //void dump(LPSTR title, PBYTE data, DWORD len)
//{ //{
// printf("==== %s ====\n", title); // printf("==== %s ====\n", title);
// for (DWORD i = 0; i < len; i++) { // for (DWORD i = 0; i < len; i+=16) {
// if (i != 0 && i % 16 == 0) { // printf("%04x: ", i);
// printf("\n"); // 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 @@ bool GetCertificateChain(LPSTR lpszKeyUsageIdentifier, PCCERT_CONTEXT pCertConte
JNIEXPORT jlong JNICALL Java_sun_security_mscapi_PRNG_getContext JNIEXPORT jlong JNICALL Java_sun_security_mscapi_PRNG_getContext
(JNIEnv *env, jclass clazz) { (JNIEnv *env, jclass clazz) {
HCRYPTPROV hCryptProv = NULL; HCRYPTPROV hCryptProv = NULL;
if(::CryptAcquireContext( if(::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
NULL, NULL,
NULL, NULL,
@ -269,7 +285,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_mscapi_PRNG_getContext
JNIEXPORT void JNICALL Java_sun_security_mscapi_PRNG_releaseContext JNIEXPORT void JNICALL Java_sun_security_mscapi_PRNG_releaseContext
(JNIEnv *env, jclass clazz, jlong ctxt) { (JNIEnv *env, jclass clazz, jlong ctxt) {
if (ctxt) { if (ctxt) {
::CryptReleaseContext((HCRYPTPROV)ctxt, 0); ::CryptReleaseContext((HCRYPTPROV)ctxt, 0); //deprecated
} }
} }
@ -304,7 +320,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
__leave; __leave;
} }
if (::CryptGenRandom( if (::CryptGenRandom( //deprecated
hCryptProv, hCryptProv,
length, length,
(BYTE *) reseedBytes) == FALSE) { (BYTE *) reseedBytes) == FALSE) {
@ -330,7 +346,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
__leave; __leave;
} }
if (::CryptGenRandom( if (::CryptGenRandom( //deprecated
hCryptProv, hCryptProv,
length, length,
(BYTE *) seedBytes) == FALSE) { (BYTE *) seedBytes) == FALSE) {
@ -359,11 +375,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
/* /*
* Class: sun_security_mscapi_KeyStore * Class: sun_security_mscapi_CKeyStore
* Method: loadKeysOrCertificateChains * 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) (JNIEnv *env, jobject obj, jstring jCertStoreName)
{ {
/** /**
@ -460,7 +476,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
else else
{ {
if (bCallerFreeProv == TRUE) { if (bCallerFreeProv == TRUE) {
::CryptReleaseContext(hCryptProv, NULL); ::CryptReleaseContext(hCryptProv, NULL); // deprecated
bCallerFreeProv = FALSE; bCallerFreeProv = FALSE;
} }
@ -473,18 +489,18 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
else else
{ {
// Private key is available // Private key is available
BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey); BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey); //deprecated
// Skip certificate if cannot find private key // Skip certificate if cannot find private key
if (bGetUserKey == FALSE) { if (bGetUserKey == FALSE) {
if (bCallerFreeProv) if (bCallerFreeProv)
::CryptReleaseContext(hCryptProv, NULL); ::CryptReleaseContext(hCryptProv, NULL); // deprecated
continue; continue;
} }
// Set cipher mode to ECB // Set cipher mode to ECB
DWORD dwCipherMode = CRYPT_MODE_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 // 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, // determine the key length by using the private key handle. However,
@ -570,9 +586,8 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
// Determine key type: RSA or DSA // Determine key type: RSA or DSA
DWORD dwData = CALG_RSA_KEYX; DWORD dwData = CALG_RSA_KEYX;
DWORD dwSize = sizeof(DWORD); DWORD dwSize = sizeof(DWORD);
::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData, ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData, //deprecated
&dwSize, NULL); &dwSize, NULL);
if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA) if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
{ {
// Generate RSA certificate chain and store into cert // Generate RSA certificate chain and store into cert
@ -614,18 +629,18 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_Key_cleanUp
(JNIEnv *env, jclass clazz, jlong hCryptProv, jlong hCryptKey) (JNIEnv *env, jclass clazz, jlong hCryptProv, jlong hCryptKey)
{ {
if (hCryptKey != NULL) if (hCryptKey != NULL)
::CryptDestroyKey((HCRYPTKEY) hCryptKey); ::CryptDestroyKey((HCRYPTKEY) hCryptKey); // deprecated
if (hCryptProv != NULL) if (hCryptProv != NULL)
::CryptReleaseContext((HCRYPTPROV) hCryptProv, NULL); ::CryptReleaseContext((HCRYPTPROV) hCryptProv, NULL); // deprecated
} }
/* /*
* Class: sun_security_mscapi_RSASignature * Class: sun_security_mscapi_CSignature
* Method: signHash * Method: signHash
* Signature: (Z[BILjava/lang/String;JJ)[B * 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, (JNIEnv *env, jclass clazz, jboolean noHashOID, jbyteArray jHash,
jint jHashSize, jstring jHashAlgorithm, jlong hCryptProv, jint jHashSize, jstring jHashAlgorithm, jlong hCryptProv,
jlong hCryptKey) jlong hCryptKey)
@ -642,7 +657,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
ALG_ID algId = MapHashAlgorithm(env, jHashAlgorithm); ALG_ID algId = MapHashAlgorithm(env, jHashAlgorithm);
// Acquire a hash object handle. // 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 // Failover to using the PROV_RSA_AES CSP
@ -651,11 +666,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
pbData[0] = '\0'; pbData[0] = '\0';
// Get name of the key container // Get name of the key container
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0); (BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle // Acquire an alternative CSP handle
if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
PROV_RSA_AES, 0) == FALSE) PROV_RSA_AES, 0) == FALSE)
{ {
@ -664,7 +679,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
} }
// Acquire a hash object handle. // Acquire a hash object handle.
if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0, if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0, //deprecated
&hHash) == FALSE) &hHash) == FALSE)
{ {
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError()); ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@ -680,7 +695,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer); env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
// Set hash value in the hash object // 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()); ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave; __leave;
@ -691,7 +706,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
ALG_ID dwAlgId; ALG_ID dwAlgId;
DWORD dwAlgIdLen = sizeof(ALG_ID); 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()); ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave; __leave;
@ -708,7 +723,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
dwFlags = CRYPT_NOHASHOID; // omit hash OID in NONEwithRSA signature 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()); ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave; __leave;
@ -718,7 +733,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
if (pSignedHashBuffer == NULL) { if (pSignedHashBuffer == NULL) {
__leave; __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()); ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave; __leave;
@ -741,21 +756,21 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
delete [] pHashBuffer; delete [] pHashBuffer;
if (hHash) if (hHash)
::CryptDestroyHash(hHash); ::CryptDestroyHash(hHash); //deprecated
if (hCryptProvAlt) if (hCryptProvAlt)
::CryptReleaseContext(hCryptProvAlt, 0); ::CryptReleaseContext(hCryptProvAlt, 0); // deprecated
} }
return jSignedHash; return jSignedHash;
} }
/* /*
* Class: sun_security_mscapi_RSASignature_PSS * Class: sun_security_mscapi_CSignature
* Method: signPssHash * Method: signCngHash
* Signature: ([BIILjava/lang/String;JJ)[B * 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, (JNIEnv *env, jclass clazz, jbyteArray jHash,
jint jHashSize, jint saltLen, jstring jHashAlgorithm, jlong hCryptProv, jint jHashSize, jint saltLen, jstring jHashAlgorithm, jlong hCryptProv,
jlong hCryptKey) jlong hCryptKey)
@ -839,11 +854,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_00024PSS_sign
} }
/* /*
* Class: sun_security_mscapi_RSASignature * Class: sun_security_mscapi_CSignature
* Method: verifySignedHash * Method: verifySignedHash
* Signature: ([BIL/java/lang/String;[BIJJ)Z * 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, (JNIEnv *env, jclass clazz, jbyteArray jHash, jint jHashSize,
jstring jHashAlgorithm, jbyteArray jSignedHash, jint jSignedHashSize, jstring jHashAlgorithm, jbyteArray jSignedHash, jint jSignedHashSize,
jlong hCryptProv, jlong hCryptKey) jlong hCryptProv, jlong hCryptKey)
@ -871,11 +886,11 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
pbData[0] = '\0'; pbData[0] = '\0';
// Get name of the key container // Get name of the key container
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0); (BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle // Acquire an alternative CSP handle
if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
PROV_RSA_AES, 0) == FALSE) PROV_RSA_AES, 0) == FALSE)
{ {
@ -907,7 +922,7 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
pSignedHashBuffer); pSignedHashBuffer);
// Set hash value in the hash object // 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) == FALSE)
{ {
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError()); ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@ -918,7 +933,7 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
// public key algorithm, so AT_SIGNATURE is used. // public key algorithm, so AT_SIGNATURE is used.
// Verify the signature // Verify the signature
if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer, if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer, //deprecated
dwSignedHashBufferLen, (HCRYPTKEY) hCryptKey, NULL, 0) == TRUE) dwSignedHashBufferLen, (HCRYPTKEY) hCryptKey, NULL, 0) == TRUE)
{ {
result = JNI_TRUE; result = JNI_TRUE;
@ -934,26 +949,26 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
delete [] pHashBuffer; delete [] pHashBuffer;
if (hHash) if (hHash)
::CryptDestroyHash(hHash); ::CryptDestroyHash(hHash); //deprecated
if (hCryptProvAlt) if (hCryptProvAlt)
::CryptReleaseContext(hCryptProvAlt, 0); ::CryptReleaseContext(hCryptProvAlt, 0); // deprecated
} }
return result; return result;
} }
/* /*
* Class: sun_security_mscapi_RSASignature_PSS * Class: sun_security_mscapi_CSignature
* Method: verifyPssSignedHash * Method: verifyCngSignedHash
* Signature: ([BI[BIILjava/lang/String;JJ)Z * 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, (JNIEnv *env, jclass clazz,
jbyteArray jHash, jint jHashSize, jbyteArray jHash, jint jHashSize,
jbyteArray jSignedHash, jint jSignedHashSize, jbyteArray jSignedHash, jint jSignedHashSize,
jint saltLen, jstring jHashAlgorithm, jint saltLen, jstring jHashAlgorithm,
jlong hCryptProv, jlong hKey) jlong hCryptProv, jlong hCryptKey)
{ {
jbyte* pHashBuffer = NULL; jbyte* pHashBuffer = NULL;
jbyte* pSignedHashBuffer = NULL; jbyte* pSignedHashBuffer = NULL;
@ -966,7 +981,7 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_00024PSS_verify
NULL, NULL,
&hk, &hk,
hCryptProv, hCryptProv,
hKey, hCryptKey,
NULL, NULL,
0)); 0));
@ -987,17 +1002,12 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_00024PSS_verify
BCRYPT_PSS_PADDING_INFO pssInfo; BCRYPT_PSS_PADDING_INFO pssInfo;
pssInfo.pszAlgId = MapHashIdentifier(env, jHashAlgorithm); pssInfo.pszAlgId = MapHashIdentifier(env, jHashAlgorithm);
pssInfo.cbSalt = saltLen; pssInfo.cbSalt = saltLen;
if (pssInfo.pszAlgId == NULL) { if (pssInfo.pszAlgId == NULL) {
ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION, ThrowExceptionWithMessage(env, SIGNATURE_EXCEPTION,
"Unrecognised hash algorithm"); "Unrecognised hash algorithm");
__leave; __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, if (::NCryptVerifySignature(hk, &pssInfo,
(BYTE *) pHashBuffer, jHashSize, (BYTE *) pHashBuffer, jHashSize,
(BYTE *) pSignedHashBuffer, jSignedHashSize, (BYTE *) pSignedHashBuffer, jSignedHashSize,
@ -1023,12 +1033,12 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_00024PSS_verify
} }
/* /*
* Class: sun_security_mscapi_RSAKeyPairGenerator * Class: sun_security_mscapi_CKeyPairGenerator_RSA
* Method: generateRSAKeyPair * Method: generateCKeyPair
* Signature: (ILjava/lang/String;)Lsun/security/mscapi/RSAKeyPair; * Signature: (Ljava/lang/String;ILjava/lang/String;)Lsun/security/mscapi/CKeyPair;
*/ */
JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateRSAKeyPair JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CKeyPairGenerator_00024RSA_generateCKeyPair
(JNIEnv *env, jclass clazz, jint keySize, jstring keyContainerName) (JNIEnv *env, jclass clazz, jstring alg, jint keySize, jstring keyContainerName)
{ {
HCRYPTPROV hCryptProv = NULL; HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKeyPair; HCRYPTKEY hKeyPair;
@ -1046,7 +1056,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
// Acquire a CSP context (create a new key container). // Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support // Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures. // for SHA-2-based signatures.
if (::CryptAcquireContext( if (::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
pszKeyContainerName, pszKeyContainerName,
NULL, NULL,
@ -1055,7 +1065,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
{ {
// Failover to using the default CSP (PROV_RSA_FULL) // Failover to using the default CSP (PROV_RSA_FULL)
if (::CryptAcquireContext( if (::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
pszKeyContainerName, pszKeyContainerName,
NULL, NULL,
@ -1067,8 +1077,8 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
} }
} }
// Generate an RSA keypair // Generate an keypair
if(::CryptGenKey( if(::CryptGenKey( //deprecated
hCryptProv, hCryptProv,
AT_KEYEXCHANGE, AT_KEYEXCHANGE,
dwFlags, dwFlags,
@ -1078,22 +1088,22 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
__leave; __leave;
} }
// Get the method ID for the RSAKeyPair constructor // Get the method ID for the CKeyPair constructor
jclass clazzRSAKeyPair = jclass clazzCKeyPair =
env->FindClass("sun/security/mscapi/RSAKeyPair"); env->FindClass("sun/security/mscapi/CKeyPair");
if (clazzRSAKeyPair == NULL) { if (clazzCKeyPair == NULL) {
__leave; __leave;
} }
jmethodID mNewRSAKeyPair = jmethodID mNewCKeyPair =
env->GetMethodID(clazzRSAKeyPair, "<init>", "(JJI)V"); env->GetMethodID(clazzCKeyPair, "<init>", "(Ljava/lang/String;JJI)V");
if (mNewRSAKeyPair == NULL) { if (mNewCKeyPair == NULL) {
__leave; __leave;
} }
// Create a new RSA keypair // Create a new keypair
keypair = env->NewObject(clazzRSAKeyPair, mNewRSAKeyPair, keypair = env->NewObject(clazzCKeyPair, mNewCKeyPair,
(jlong) hCryptProv, (jlong) hKeyPair, keySize); alg, (jlong) hCryptProv, (jlong) hKeyPair, keySize);
} }
__finally __finally
@ -1109,18 +1119,18 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
} }
/* /*
* Class: sun_security_mscapi_Key * Class: sun_security_mscapi_CKey
* Method: getContainerName * Method: getContainerName
* Signature: (J)Ljava/lang/String; * 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) (JNIEnv *env, jclass jclazz, jlong hCryptProv)
{ {
DWORD cbData = 256; DWORD cbData = 256;
BYTE pbData[256]; BYTE pbData[256];
pbData[0] = '\0'; pbData[0] = '\0';
::CryptGetProvParam( ::CryptGetProvParam( //deprecated
(HCRYPTPROV)hCryptProv, (HCRYPTPROV)hCryptProv,
PP_CONTAINER, PP_CONTAINER,
(BYTE *)pbData, (BYTE *)pbData,
@ -1131,17 +1141,17 @@ JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getContainerName
} }
/* /*
* Class: sun_security_mscapi_Key * Class: sun_security_mscapi_CKey
* Method: getKeyType * Method: getKeyType
* Signature: (J)Ljava/lang/String; * 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) (JNIEnv *env, jclass jclazz, jlong hCryptKey)
{ {
ALG_ID dwAlgId; ALG_ID dwAlgId;
DWORD dwAlgIdLen = sizeof(ALG_ID); 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) { if (CALG_RSA_SIGN == dwAlgId) {
return env->NewStringUTF("Signature"); return env->NewStringUTF("Signature");
@ -1161,11 +1171,11 @@ JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getKeyType
} }
/* /*
* Class: sun_security_mscapi_KeyStore * Class: sun_security_mscapi_CKeyStore
* Method: storeCertificate * Method: storeCertificate
* Signature: (Ljava/lang/String;Ljava/lang/String;[BIJJ)V * 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, (JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName,
jbyteArray jCertEncoding, jint jCertEncodingSize, jlong hCryptProv, jbyteArray jCertEncoding, jint jCertEncodingSize, jlong hCryptProv,
jlong hCryptKey) jlong hCryptKey)
@ -1240,7 +1250,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
DWORD dwDataLen; DWORD dwDataLen;
// Get the name of the key container // Get the name of the key container
if (! ::CryptGetProvParam( if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv, (HCRYPTPROV) hCryptProv,
PP_CONTAINER, PP_CONTAINER,
NULL, NULL,
@ -1256,7 +1266,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
__leave; __leave;
} }
if (! ::CryptGetProvParam( if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv, (HCRYPTPROV) hCryptProv,
PP_CONTAINER, PP_CONTAINER,
(BYTE *) pszContainerName, (BYTE *) pszContainerName,
@ -1283,7 +1293,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
// Get the name of the provider // Get the name of the provider
if (! ::CryptGetProvParam( if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv, (HCRYPTPROV) hCryptProv,
PP_NAME, PP_NAME,
NULL, NULL,
@ -1299,7 +1309,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
__leave; __leave;
} }
if (! ::CryptGetProvParam( if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv, (HCRYPTPROV) hCryptProv,
PP_NAME, PP_NAME,
(BYTE *) pszProviderName, (BYTE *) pszProviderName,
@ -1325,7 +1335,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
keyProviderInfo.pwszProvName = pwszProviderName; keyProviderInfo.pwszProvName = pwszProviderName;
// Get and set the type of the provider // Get and set the type of the provider
if (! ::CryptGetProvParam( if (! ::CryptGetProvParam( //deprecated
(HCRYPTPROV) hCryptProv, (HCRYPTPROV) hCryptProv,
PP_PROVTYPE, PP_PROVTYPE,
(LPBYTE) &keyProviderInfo.dwProvType, (LPBYTE) &keyProviderInfo.dwProvType,
@ -1344,7 +1354,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
keyProviderInfo.rgProvParam = NULL; keyProviderInfo.rgProvParam = NULL;
// Get the key's algorithm ID // Get the key's algorithm ID
if (! ::CryptGetKeyParam( if (! ::CryptGetKeyParam( //deprecated
(HCRYPTKEY) hCryptKey, (HCRYPTKEY) hCryptKey,
KP_ALGID, KP_ALGID,
(LPBYTE) &keyProviderInfo.dwKeySpec, (LPBYTE) &keyProviderInfo.dwKeySpec,
@ -1423,11 +1433,11 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate
} }
/* /*
* Class: sun_security_mscapi_KeyStore * Class: sun_security_mscapi_CKeyStore
* Method: removeCertificate * Method: removeCertificate
* Signature: (Ljava/lang/String;Ljava/lang/String;[BI)V * 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, (JNIEnv *env, jobject obj, jstring jCertStoreName, jstring jCertAliasName,
jbyteArray jCertEncoding, jint jCertEncodingSize) { jbyteArray jCertEncoding, jint jCertEncodingSize) {
@ -1539,11 +1549,11 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_removeCertificate
} }
/* /*
* Class: sun_security_mscapi_KeyStore * Class: sun_security_mscapi_CKeyStore
* Method: destroyKeyContainer * Method: destroyKeyContainer
* Signature: (Ljava/lang/String;)V * 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) (JNIEnv *env, jobject clazz, jstring keyContainerName)
{ {
HCRYPTPROV hCryptProv = NULL; HCRYPTPROV hCryptProv = NULL;
@ -1565,7 +1575,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_destroyKeyContainer
} }
// Acquire a CSP context (to the key container). // Acquire a CSP context (to the key container).
if (::CryptAcquireContext( if (::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
pszKeyContainerName, pszKeyContainerName,
NULL, NULL,
@ -1588,11 +1598,11 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_destroyKeyContainer
} }
/* /*
* Class: sun_security_mscapi_RSACipher * Class: sun_security_mscapi_CRSACipher
* Method: encryptDecrypt * Method: encryptDecrypt
* Signature: ([BIJZ)[B * 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, (JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
jboolean doEncrypt) jboolean doEncrypt)
{ {
@ -1614,7 +1624,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
if (doEncrypt == JNI_TRUE) { if (doEncrypt == JNI_TRUE) {
// encrypt // encrypt
if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
&dwDataLen, dwBufLen)) { &dwDataLen, dwBufLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError()); ThrowException(env, KEY_EXCEPTION, GetLastError());
@ -1637,7 +1647,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
} }
// decrypt // decrypt
if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, if (! ::CryptDecrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData, //deprecated
&dwBufLen)) { &dwBufLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError()); ThrowException(env, KEY_EXCEPTION, GetLastError());
@ -1661,11 +1671,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
} }
/* /*
* Class: sun_security_mscapi_RSAPublicKey * Class: sun_security_mscapi_CPublicKey
* Method: getPublicKeyBlob * Method: getPublicKeyBlob
* Signature: (J)[B * 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) { (JNIEnv *env, jobject clazz, jlong hCryptKey) {
jbyteArray blob = NULL; jbyteArray blob = NULL;
@ -1676,7 +1686,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyB
{ {
// Determine the size of the blob // Determine the size of the blob
if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL, if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL, //deprecated
&dwBlobLen)) { &dwBlobLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError()); ThrowException(env, KEY_EXCEPTION, GetLastError());
@ -1689,7 +1699,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyB
} }
// Generate key blob // Generate key blob
if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, //deprecated
pbKeyBlob, &dwBlobLen)) { pbKeyBlob, &dwBlobLen)) {
ThrowException(env, KEY_EXCEPTION, GetLastError()); ThrowException(env, KEY_EXCEPTION, GetLastError());
@ -1712,11 +1722,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyB
} }
/* /*
* Class: sun_security_mscapi_RSAPublicKey * Class: sun_security_mscapi_CPublicKey_CRSAPublicKey
* Method: getExponent * Method: getExponent
* Signature: ([B)[B * 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) { (JNIEnv *env, jobject clazz, jbyteArray jKeyBlob) {
jbyteArray exponent = NULL; jbyteArray exponent = NULL;
@ -1768,11 +1778,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getExponent
} }
/* /*
* Class: sun_security_mscapi_RSAPublicKey * Class: sun_security_mscapi_CPublicKey_CRSAPublicKey
* Method: getModulus * Method: getModulus
* Signature: ([B)[B * 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) { (JNIEnv *env, jobject clazz, jbyteArray jKeyBlob) {
jbyteArray modulus = NULL; jbyteArray modulus = NULL;
@ -2041,11 +2051,11 @@ jbyteArray generateKeyBlob(
} }
/* /*
* Class: sun_security_mscapi_KeyStore * Class: sun_security_mscapi_CKeyStore
* Method: generatePrivateKeyBlob * Method: generateRSAPrivateKeyBlob
* Signature: (I[B[B[B[B[B[B[B[B)[B * 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, (JNIEnv *env, jobject clazz,
jint jKeyBitLength, jint jKeyBitLength,
jbyteArray jModulus, jbyteArray jModulus,
@ -2063,11 +2073,11 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_KeyStore_generatePrivateKe
} }
/* /*
* Class: sun_security_mscapi_RSASignature * Class: sun_security_mscapi_CSignature_RSA
* Method: generatePublicKeyBlob * Method: generatePublicKeyBlob
* Signature: (I[B[B)[B * 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, (JNIEnv *env, jclass clazz,
jint jKeyBitLength, jint jKeyBitLength,
jbyteArray jModulus, jbyteArray jModulus,
@ -2078,13 +2088,13 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_generatePubli
} }
/* /*
* Class: sun_security_mscapi_KeyStore * Class: sun_security_mscapi_CKeyStore
* Method: storePrivateKey * 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 JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CKeyStore_storePrivateKey
(JNIEnv *env, jobject clazz, jbyteArray keyBlob, jstring keyContainerName, (JNIEnv *env, jobject clazz, jstring alg, jbyteArray keyBlob,
jint keySize) jstring keyContainerName, jint keySize)
{ {
HCRYPTPROV hCryptProv = NULL; HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL; HCRYPTKEY hKey = NULL;
@ -2106,7 +2116,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_KeyStore_storePrivateKey
} }
// Acquire a CSP context (create a new key container). // Acquire a CSP context (create a new key container).
if (::CryptAcquireContext( if (::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
pszKeyContainerName, pszKeyContainerName,
NULL, NULL,
@ -2118,7 +2128,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_KeyStore_storePrivateKey
} }
// Import the private key // Import the private key
if (::CryptImportKey( if (::CryptImportKey( //deprecated
hCryptProv, hCryptProv,
pbKeyBlob, pbKeyBlob,
dwBlobLen, dwBlobLen,
@ -2130,22 +2140,23 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_KeyStore_storePrivateKey
__leave; __leave;
} }
// Get the method ID for the RSAPrivateKey constructor // Get the method ID for the CPrivateKey constructor
jclass clazzRSAPrivateKey = jclass clazzCPrivateKey =
env->FindClass("sun/security/mscapi/RSAPrivateKey"); env->FindClass("sun/security/mscapi/CPrivateKey");
if (clazzRSAPrivateKey == NULL) { if (clazzCPrivateKey == NULL) {
__leave; __leave;
} }
jmethodID mNewRSAPrivateKey = jmethodID mNewCPrivateKey =
env->GetMethodID(clazzRSAPrivateKey, "<init>", "(JJI)V"); env->GetStaticMethodID(clazzCPrivateKey, "of",
if (mNewRSAPrivateKey == NULL) { "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPrivateKey;");
if (mNewCPrivateKey == NULL) {
__leave; __leave;
} }
// Create a new RSA private key // Create a new private key
privateKey = env->NewObject(clazzRSAPrivateKey, mNewRSAPrivateKey, privateKey = env->CallStaticObjectMethod(clazzCPrivateKey, mNewCPrivateKey,
(jlong) hCryptProv, (jlong) hKey, keySize); alg, (jlong) hCryptProv, (jlong) hKey, keySize);
} }
__finally __finally
@ -2165,12 +2176,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_KeyStore_storePrivateKey
} }
/* /*
* Class: sun_security_mscapi_RSASignature * Class: sun_security_mscapi_CSignature
* Method: importPublicKey * 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 JNIEXPORT jobject JNICALL Java_sun_security_mscapi_CSignature_importPublicKey
(JNIEnv *env, jclass clazz, jbyteArray keyBlob, jint keySize) (JNIEnv *env, jclass clazz, jstring alg, jbyteArray keyBlob, jint keySize)
{ {
HCRYPTPROV hCryptProv = NULL; HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL; HCRYPTKEY hKey = NULL;
@ -2189,7 +2200,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
// Acquire a CSP context (create a new key container). // Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support // Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures. // for SHA-2-based signatures.
if (::CryptAcquireContext( if (::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
NULL, NULL,
NULL, NULL,
@ -2198,7 +2209,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
{ {
// Failover to using the default CSP (PROV_RSA_FULL) // Failover to using the default CSP (PROV_RSA_FULL)
if (::CryptAcquireContext( if (::CryptAcquireContext( //deprecated
&hCryptProv, &hCryptProv,
NULL, NULL,
NULL, NULL,
@ -2211,7 +2222,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
} }
// Import the public key // Import the public key
if (::CryptImportKey( if (::CryptImportKey( //deprecated
hCryptProv, hCryptProv,
pbKeyBlob, pbKeyBlob,
dwBlobLen, dwBlobLen,
@ -2223,22 +2234,23 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
__leave; __leave;
} }
// Get the method ID for the RSAPublicKey constructor // Get the method ID for the CPublicKey constructor
jclass clazzRSAPublicKey = jclass clazzCPublicKey =
env->FindClass("sun/security/mscapi/RSAPublicKey"); env->FindClass("sun/security/mscapi/CPublicKey");
if (clazzRSAPublicKey == NULL) { if (clazzCPublicKey == NULL) {
__leave; __leave;
} }
jmethodID mNewRSAPublicKey = jmethodID mNewCPublicKey =
env->GetMethodID(clazzRSAPublicKey, "<init>", "(JJI)V"); env->GetStaticMethodID(clazzCPublicKey, "of",
if (mNewRSAPublicKey == NULL) { "(Ljava/lang/String;JJI)Lsun/security/mscapi/CPublicKey;");
if (mNewCPublicKey == NULL) {
__leave; __leave;
} }
// Create a new RSA public key // Create a new public key
publicKey = env->NewObject(clazzRSAPublicKey, mNewRSAPublicKey, publicKey = env->CallStaticObjectMethod(clazzCPublicKey, mNewCPublicKey,
(jlong) hCryptProv, (jlong) hKey, keySize); alg, (jlong) hCryptProv, (jlong) hKey, keySize);
} }
__finally __finally

View file

@ -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);
}
}