8218723: Use SunJCE Mac in SecretKeyFactory PBKDF2 implementation
Reviewed-by: apetcher
This commit is contained in:
parent
7954db81f8
commit
de75770ce9
src/java.base/share/classes/com/sun/crypto/provider
test/jdk/javax/crypto/SecretKeyFactory
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2019, 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
|
||||
@ -113,12 +113,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
||||
} else if (keyLength < 0) {
|
||||
throw new InvalidKeySpecException("Key length is negative");
|
||||
}
|
||||
this.prf = Mac.getInstance(prfAlgo);
|
||||
// SunPKCS11 requires a non-empty PBE password
|
||||
if (passwdBytes.length == 0 &&
|
||||
this.prf.getProvider().getName().startsWith("SunPKCS11")) {
|
||||
this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance());
|
||||
}
|
||||
this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance());
|
||||
this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// not gonna happen; re-throw just in case
|
||||
@ -207,7 +202,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
||||
}
|
||||
}
|
||||
} catch (GeneralSecurityException gse) {
|
||||
throw new RuntimeException("Error deriving PBKDF2 keys");
|
||||
throw new RuntimeException("Error deriving PBKDF2 keys", gse);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 8218723
|
||||
* @summary Use SunJCE Mac in SecretKeyFactory PBKDF2 implementation
|
||||
* @library evilprov.jar
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main/othervm SecKeyFacSunJCEPrf
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import com.evilprovider.*;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
public class SecKeyFacSunJCEPrf {
|
||||
|
||||
// One of the PBKDF2 HMAC-SHA1 test vectors from RFC 6070
|
||||
private static final byte[] SALT = "salt".getBytes();
|
||||
private static final char[] PASS = "password".toCharArray();
|
||||
private static final int ITER = 4096;
|
||||
private static final byte[] EXP_OUT = Convert.hexStringToByteArray(
|
||||
"4B007901B765489ABEAD49D926F721D065A429C1");
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Instantiate the Evil Provider and insert it in the
|
||||
// most-preferred position.
|
||||
Provider evilProv = new EvilProvider();
|
||||
System.out.println("3rd Party Provider: " + evilProv);
|
||||
Security.insertProviderAt(evilProv, 1);
|
||||
|
||||
SecretKeyFactory pbkdf2 =
|
||||
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "SunJCE");
|
||||
PBEKeySpec pbks = new PBEKeySpec(PASS, SALT, ITER, 160);
|
||||
|
||||
SecretKey secKey1 = pbkdf2.generateSecret(pbks);
|
||||
System.out.println("PBKDF2WithHmacSHA1:\n" +
|
||||
Convert.byteArrayToHexString(secKey1.getEncoded()));
|
||||
if (Arrays.equals(secKey1.getEncoded(), EXP_OUT)) {
|
||||
System.out.println("Test Vector Passed");
|
||||
} else {
|
||||
System.out.println("Test Vector Failed");
|
||||
System.out.println("Expected Output:\n" +
|
||||
Convert.byteArrayToHexString(EXP_OUT));
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
test/jdk/javax/crypto/SecretKeyFactory/evilprov.jar
Normal file
BIN
test/jdk/javax/crypto/SecretKeyFactory/evilprov.jar
Normal file
Binary file not shown.
55
test/jdk/javax/crypto/SecretKeyFactory/evilprov/Makefile
Normal file
55
test/jdk/javax/crypto/SecretKeyFactory/evilprov/Makefile
Normal file
@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright (c) 2019, 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.
|
||||
#
|
||||
|
||||
# Java paths
|
||||
#JAVA_BASE=PATH_TO_JAVA_IMG_DIR
|
||||
JAVABIN=$(JAVA_BASE)/bin
|
||||
JAVAC=$(JAVABIN)/javac
|
||||
JAVA=$(JAVABIN)/java
|
||||
JAR=$(JAVABIN)/jar
|
||||
JARSIGNER=$(JAVABIN)/jarsigner
|
||||
|
||||
# Compile-time flags and paths
|
||||
JFLAGS=-Xlint:all
|
||||
SRCPATH=com/evilprovider
|
||||
CLASSDST=classes
|
||||
|
||||
PROVJAR=evilprov.jar
|
||||
KSTORE=PATH_TO_KEYSTORE
|
||||
KALIAS=PLACE_SIGNING_ALIAS_HERE
|
||||
MODVER=1.0
|
||||
|
||||
all: $(PROVJAR)
|
||||
|
||||
%.class: %.java
|
||||
mkdir -p $(CLASSDST)
|
||||
$(JAVAC) -d $(CLASSDST) $(JFLAGS) $<
|
||||
|
||||
$(PROVJAR): $(SRCPATH)/EvilHmacSHA1.class $(SRCPATH)/EvilProvider.class module-info.class
|
||||
$(JAR) --create --file $(PROVJAR) --module-version $(MODVER) -C $(CLASSDST) .
|
||||
|
||||
signed: $(PROVJAR)
|
||||
jarsigner -keystore $(KSTORE) $(PROVJAR).jar $(KALIAS)
|
||||
|
||||
clean:
|
||||
rm -rf $(CLASSDST) $(PROVJAR)
|
15
test/jdk/javax/crypto/SecretKeyFactory/evilprov/README
Normal file
15
test/jdk/javax/crypto/SecretKeyFactory/evilprov/README
Normal file
@ -0,0 +1,15 @@
|
||||
Everything in this directory is dedicated to building the EvilProvider
|
||||
used with the SecKeyFacSunJCEPRF test (JDK-8218723).
|
||||
|
||||
The makefile does require a JDK image path to be provided through the
|
||||
JAVA_BASE makefile variable. As an example:
|
||||
|
||||
make JAVA_BASE=/usr/java/jdk-11.0.1 evilprov
|
||||
|
||||
Since the EvilProvider is a modular jar, JDK 9 or later should be used.
|
||||
|
||||
For OpenJDK, no signing is required. If signing is required (for use
|
||||
with Oracle JDK, for instance), you must obtain a JCE signing certificate
|
||||
and place it in a keystore, then run the "signed" makefile target (it will
|
||||
build the jar file if it does not already exist).
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 com.evilprovider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.crypto.*;
|
||||
|
||||
public final class EvilHmacSHA1 extends MacSpi {
|
||||
private final Mac internalMac;
|
||||
|
||||
public EvilHmacSHA1() throws GeneralSecurityException {
|
||||
internalMac = Mac.getInstance("HmacSHA1", "SunJCE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] engineDoFinal() {
|
||||
return internalMac.doFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int engineGetMacLength() {
|
||||
return internalMac.getMacLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(Key key, AlgorithmParameterSpec spec)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
SecretKey sKey;
|
||||
if (key instanceof SecretKey) {
|
||||
sKey = (SecretKey)key;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Key must be a SecretKey");
|
||||
}
|
||||
|
||||
byte[] sKeyEnc = sKey.getEncoded();
|
||||
int keyBits = sKeyEnc.length * 8;
|
||||
if (keyBits < 160) {
|
||||
throw new IllegalArgumentException("Key must be at least 160 bits");
|
||||
}
|
||||
|
||||
// Pass through to init
|
||||
internalMac.init(key, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineReset() {
|
||||
internalMac.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineUpdate(byte input) {
|
||||
internalMac.update(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineUpdate(byte[] input, int offset, int len) {
|
||||
internalMac.update(input, offset, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineUpdate(ByteBuffer input) {
|
||||
internalMac.update(input);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 com.evilprovider;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
public final class EvilProvider extends Provider {
|
||||
|
||||
private static final long serialVersionUID = 11223344550000L;
|
||||
|
||||
public EvilProvider() {
|
||||
super("EvilProvider", "1.0", "Evil Provider");
|
||||
putService(new Provider.Service(this, "Mac", "HmacSHA1",
|
||||
"com.evilprovider.EvilHmacSHA1", null, null));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides the evil provider
|
||||
*
|
||||
* @provides java.security.Provider
|
||||
*
|
||||
* @moduleGraph
|
||||
*/
|
||||
module jdk.evilprovider {
|
||||
provides java.security.Provider with com.evilprovider.EvilProvider;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user