8146293: Add support for RSASSA-PSS Signature algorithm

Add RSASSA-PSS key and signature support to SunRsaSign provider

Reviewed-by: wetmore
This commit is contained in:
Valerie Peng 2018-05-21 23:40:52 +00:00
parent 6216182dd1
commit 9e8d9fe1ee
79 changed files with 5489 additions and 627 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -137,6 +137,10 @@ public final class OAEPParameters extends AlgorithmParametersSpi {
mgfSpec = MGF1ParameterSpec.SHA384;
} else if (mgfDigestName.equals("SHA-512")) {
mgfSpec = MGF1ParameterSpec.SHA512;
} else if (mgfDigestName.equals("SHA-512/224")) {
mgfSpec = MGF1ParameterSpec.SHA512_224;
} else if (mgfDigestName.equals("SHA-512/256")) {
mgfSpec = MGF1ParameterSpec.SHA512_256;
} else {
throw new IOException(
"Unrecognized message digest algorithm");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -44,13 +44,15 @@ import sun.security.util.KeyUtil;
/**
* RSA cipher implementation. Supports RSA en/decryption and signing/verifying
* using PKCS#1 v1.5 padding and without padding (raw RSA). Note that raw RSA
* is supported mostly for completeness and should only be used in rare cases.
* using both PKCS#1 v1.5 and OAEP (v2.2) paddings and without padding (raw RSA).
* Note that raw RSA is supported mostly for completeness and should only be
* used in rare cases.
*
* Objects should be instantiated by calling Cipher.getInstance() using the
* following algorithm names:
* . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype)
* is selected based on the en/decryption mode and public/private key used
* . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 v1.5 padding.
* . "RSA/ECB/OAEPwith<hash>andMGF1Padding" (or "RSA/ECB/OAEPPadding") for
* PKCS#1 v2.2 padding.
* . "RSA/ECB/NoPadding" for rsa RSA.
*
* We only do one RSA operation per doFinal() call. If the application passes
@ -81,7 +83,7 @@ public final class RSACipher extends CipherSpi {
private static final String PAD_NONE = "NoPadding";
// constant for PKCS#1 v1.5 RSA
private static final String PAD_PKCS1 = "PKCS1Padding";
// constant for PKCS#2 v2.0 OAEP with MGF1
// constant for PKCS#2 v2.2 OAEP with MGF1
private static final String PAD_OAEP_MGF1 = "OAEP";
// current mode, one of MODE_* above. Set when init() is called

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -132,7 +132,9 @@ public final class SunJCE extends Provider {
+ "|OAEPWITHSHA-224ANDMGF1PADDING"
+ "|OAEPWITHSHA-256ANDMGF1PADDING"
+ "|OAEPWITHSHA-384ANDMGF1PADDING"
+ "|OAEPWITHSHA-512ANDMGF1PADDING");
+ "|OAEPWITHSHA-512ANDMGF1PADDING"
+ "|OAEPWITHSHA-512/224ANDMGF1PADDING"
+ "|OAEPWITHSHA-512/256ANDMGF1PADDING");
put("Cipher.RSA SupportedKeyClasses",
"java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -284,6 +284,7 @@ public abstract class Signature extends SignatureSpi {
signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
signatureInfo.put("sun.security.rsa.RSAPSSSignature", TRUE);
signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE);
signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -25,14 +25,9 @@
package java.security.cert;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.security.Principal;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Signature;
import java.security.*;
import java.security.spec.*;
import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
@ -41,6 +36,7 @@ import java.util.Set;
import java.util.Arrays;
import sun.security.x509.X509CRLImpl;
import sun.security.util.SignatureUtil;
/**
* <p>
@ -246,8 +242,19 @@ public abstract class X509CRL extends CRL implements X509Extension {
Signature sig = (sigProvider == null)
? Signature.getInstance(getSigAlgName())
: Signature.getInstance(getSigAlgName(), sigProvider);
sig.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selections occur when key is set
try {
SignatureUtil.specialSetParameter(sig, getSigAlgParams());
} catch (ProviderException e) {
throw new CRLException(e.getMessage(), e.getCause());
} catch (InvalidAlgorithmParameterException e) {
throw new CRLException(e);
}
byte[] tbsCRL = getTBSCertList();
sig.update(tbsCRL, 0, tbsCRL.length);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -27,12 +27,14 @@ package java.security.cert;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.security.auth.x500.X500Principal;
import sun.security.x509.X509CertImpl;
import sun.security.util.SignatureUtil;
/**
* <p>
@ -677,8 +679,19 @@ implements X509Extension {
Signature sig = (sigProvider == null)
? Signature.getInstance(getSigAlgName())
: Signature.getInstance(getSigAlgName(), sigProvider);
sig.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selections occur when key is set
try {
SignatureUtil.specialSetParameter(sig, getSigAlgParams());
} catch (ProviderException e) {
throw new CertificateException(e.getMessage(), e.getCause());
} catch (InvalidAlgorithmParameterException e) {
throw new CertificateException(e);
}
byte[] tbsCert = getTBSCertificate();
sig.update(tbsCert, 0, tbsCert.length);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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
@ -26,9 +26,12 @@
package java.security.interfaces;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
/**
* The interface to an RSA public or private key.
* The interface to a public or private key in
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* such as those for RSA, or RSASSA-PSS algorithms.
*
* @author Jan Luehe
*
@ -46,4 +49,20 @@ public interface RSAKey {
* @return the modulus
*/
public BigInteger getModulus();
/**
* Returns the parameters associated with this key.
* The parameters are optional and may be either
* explicitly specified or implicitly created during
* key pair generation.
*
* @implSpec
* The default implementation returns {@code null}.
*
* @return the associated parameters, may be null
* @since 11
*/
default AlgorithmParameterSpec getParams() {
return null;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -30,8 +30,8 @@ import java.security.spec.RSAOtherPrimeInfo;
/**
* The interface to an RSA multi-prime private key, as defined in the
* PKCS#1 v2.1, using the <i>Chinese Remainder Theorem</i>
* (CRT) information values.
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* using the <i>Chinese Remainder Theorem</i> (CRT) information values.
*
* @author Valerie Peng
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -28,7 +28,8 @@ package java.security.interfaces;
import java.math.BigInteger;
/**
* The interface to an RSA private key, as defined in the PKCS#1 standard,
* The interface to an RSA private key, as defined in the
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* using the <i>Chinese Remainder Theorem</i> (CRT) information values.
*
* @author Jan Luehe

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -51,7 +51,7 @@
* <h2>Package Specification</h2>
*
* <ul>
* <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993 </li>
* <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 186:
* Digital Signature Standard (DSS) </li>
* </ul>

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -29,23 +29,31 @@ import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies the set of parameters used with mask generation
* function MGF1 in OAEP Padding and RSA-PSS signature scheme, as
* function MGF1 in OAEP Padding and RSASSA-PSS signature scheme, as
* defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1 v2.1</a>
* standard.
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
*
* <p>Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
* MGF1Parameters ::= OAEP-PSSDigestAlgorthms
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
* </pre>
* where
* <pre>
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL },
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
* </pre>
@ -59,31 +67,47 @@ import java.security.spec.AlgorithmParameterSpec;
public class MGF1ParameterSpec implements AlgorithmParameterSpec {
/**
* The MGF1ParameterSpec which uses "SHA-1" message digest.
* The MGF1ParameterSpec which uses "SHA-1" message digest
*/
public static final MGF1ParameterSpec SHA1 =
new MGF1ParameterSpec("SHA-1");
/**
* The MGF1ParameterSpec which uses "SHA-224" message digest.
* The MGF1ParameterSpec which uses "SHA-224" message digest
*/
public static final MGF1ParameterSpec SHA224 =
new MGF1ParameterSpec("SHA-224");
/**
* The MGF1ParameterSpec which uses "SHA-256" message digest.
* The MGF1ParameterSpec which uses "SHA-256" message digest
*/
public static final MGF1ParameterSpec SHA256 =
new MGF1ParameterSpec("SHA-256");
/**
* The MGF1ParameterSpec which uses "SHA-384" message digest.
* The MGF1ParameterSpec which uses "SHA-384" message digest
*/
public static final MGF1ParameterSpec SHA384 =
new MGF1ParameterSpec("SHA-384");
/**
* The MGF1ParameterSpec which uses SHA-512 message digest.
* The MGF1ParameterSpec which uses SHA-512 message digest
*/
public static final MGF1ParameterSpec SHA512 =
new MGF1ParameterSpec("SHA-512");
/**
* The MGF1ParameterSpec which uses SHA-512/224 message digest
*/
public static final MGF1ParameterSpec SHA512_224 =
new MGF1ParameterSpec("SHA-512/224");
/**
* The MGF1ParameterSpec which uses SHA-512/256 message digest
*/
public static final MGF1ParameterSpec SHA512_256 =
new MGF1ParameterSpec("SHA-512/256");
private String mdName;
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -25,37 +25,43 @@
package java.security.spec;
import java.math.BigInteger;
import java.util.Objects;
import java.security.spec.MGF1ParameterSpec;
/**
* This class specifies a parameter spec for RSA-PSS signature scheme,
* This class specifies a parameter spec for RSASSA-PSS signature scheme,
* as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS#1 v2.1</a>
* standard.
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
*
* <p>Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
* RSASSA-PSS-params ::= SEQUENCE {
* hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
* maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
* saltLength [2] INTEGER DEFAULT 20,
* trailerField [3] INTEGER DEFAULT 1
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
* saltLength [2] INTEGER DEFAULT 20,
* trailerField [3] TrailerField DEFAULT trailerFieldBC(1)
* }
* </pre>
* where
* <pre>
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
* TrailerField ::= INTEGER { trailerFieldBC(1) }
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL },
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
*
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
* { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
* </pre>
@ -78,55 +84,62 @@ import java.security.spec.MGF1ParameterSpec;
public class PSSParameterSpec implements AlgorithmParameterSpec {
private String mdName = "SHA-1";
private String mgfName = "MGF1";
private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
private int saltLen = 20;
private int trailerField = 1;
private final String mdName;
private final String mgfName;
private final AlgorithmParameterSpec mgfSpec;
private final int saltLen;
private final int trailerField;
/**
* The PSS parameter set with all default values.
* The {@code TrailerFieldBC} constant as defined in PKCS#1
*
* @since 11
*/
public static final int TRAILER_FIELD_BC = 1;
/**
* The PSS parameter set with all default values
*
* @since 1.5
*/
public static final PSSParameterSpec DEFAULT = new PSSParameterSpec();
public static final PSSParameterSpec DEFAULT = new PSSParameterSpec
("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, TRAILER_FIELD_BC);
/**
* Constructs a new {@code PSSParameterSpec} as defined in
* the PKCS #1 standard using the default values.
*/
// disallowed
private PSSParameterSpec() {
throw new RuntimeException("default constructor not allowed");
}
/**
* Creates a new {@code PSSParameterSpec} as defined in
* the PKCS #1 standard using the specified message digest,
* mask generation function, parameters for mask generation
* function, salt length, and trailer field values.
*
* @param mdName the algorithm name of the hash function.
* @param mgfName the algorithm name of the mask generation
* function.
* @param mgfSpec the parameters for the mask generation
* function. If null is specified, null will be returned by
* getMGFParameters().
* @param saltLen the length of salt.
* @param trailerField the value of the trailer field.
* @exception NullPointerException if {@code mdName},
* or {@code mgfName} is null.
* @exception IllegalArgumentException if {@code saltLen}
* or {@code trailerField} is less than 0.
* @param mdName the algorithm name of the hash function
* @param mgfName the algorithm name of the mask generation function
* @param mgfSpec the parameters for the mask generation function.
* If null is specified, null will be returned by
* getMGFParameters().
* @param saltLen the length of salt
* @param trailerField the value of the trailer field
* @exception NullPointerException if {@code mdName}, or {@code mgfName}
* is null
* @exception IllegalArgumentException if {@code saltLen} or
* {@code trailerField} is less than 0
* @since 1.5
*/
public PSSParameterSpec(String mdName, String mgfName,
AlgorithmParameterSpec mgfSpec,
int saltLen, int trailerField) {
if (mdName == null) {
throw new NullPointerException("digest algorithm is null");
}
if (mgfName == null) {
throw new NullPointerException("mask generation function " +
"algorithm is null");
}
AlgorithmParameterSpec mgfSpec, int saltLen, int trailerField) {
Objects.requireNonNull(mdName, "digest algorithm is null");
Objects.requireNonNull(mgfName,
"mask generation function algorithm is null");
if (saltLen < 0) {
throw new IllegalArgumentException("negative saltLen value: " +
saltLen);
@ -147,23 +160,19 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
* using the specified salt length and other default values as
* defined in PKCS#1.
*
* @param saltLen the length of salt in bits to be used in PKCS#1
* PSS encoding.
* @param saltLen the length of salt in bytes to be used in PKCS#1
* PSS encoding
* @exception IllegalArgumentException if {@code saltLen} is
* less than 0.
* less than 0
*/
public PSSParameterSpec(int saltLen) {
if (saltLen < 0) {
throw new IllegalArgumentException("negative saltLen value: " +
saltLen);
}
this.saltLen = saltLen;
this("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, saltLen, TRAILER_FIELD_BC);
}
/**
* Returns the message digest algorithm name.
*
* @return the message digest algorithm name.
* @return the message digest algorithm name
* @since 1.5
*/
public String getDigestAlgorithm() {
@ -173,7 +182,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
/**
* Returns the mask generation function algorithm name.
*
* @return the mask generation function algorithm name.
* @return the mask generation function algorithm name
*
* @since 1.5
*/
@ -184,7 +193,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
/**
* Returns the parameters for the mask generation function.
*
* @return the parameters for the mask generation function.
* @return the parameters for the mask generation function
* @since 1.5
*/
public AlgorithmParameterSpec getMGFParameters() {
@ -192,18 +201,18 @@ public class PSSParameterSpec implements AlgorithmParameterSpec {
}
/**
* Returns the salt length in bits.
* Returns the salt length in bytes.
*
* @return the salt length.
* @return the salt length
*/
public int getSaltLength() {
return saltLen;
}
/**
* Returns the value for the trailer field, i.e. bc in PKCS#1 v2.1.
* Returns the value for the trailer field.
*
* @return the value for the trailer field, i.e. bc in PKCS#1 v2.1.
* @return the value for the trailer field
* @since 1.5
*/
public int getTrailerField() {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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
@ -43,6 +43,7 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
private int keysize;
private BigInteger publicExponent;
private AlgorithmParameterSpec keyParams;
/**
* The public-exponent value F0 = 3.
@ -55,15 +56,30 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
public static final BigInteger F4 = BigInteger.valueOf(65537);
/**
* Constructs a new {@code RSAParameterSpec} object from the
* given keysize and public-exponent value.
* Constructs a new {@code RSAKeyGenParameterSpec} object from the
* given keysize, public-exponent value, and null key parameters.
*
* @param keysize the modulus size (specified in number of bits)
* @param publicExponent the public exponent
*/
public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) {
this(keysize, publicExponent, null);
}
/**
* Constructs a new {@code RSAKeyGenParameterSpec} object from the
* given keysize, public-exponent value, and key parameters.
*
* @param keysize the modulus size (specified in number of bits)
* @param publicExponent the public exponent
* @param keyParams the key parameters, may be null
* @since 11
*/
public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent,
AlgorithmParameterSpec keyParams) {
this.keysize = keysize;
this.publicExponent = publicExponent;
this.keyParams = keyParams;
}
/**
@ -83,4 +99,15 @@ public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
public BigInteger getPublicExponent() {
return publicExponent;
}
/**
* Returns the parameters to be associated with key.
*
* @return the associated parameters, may be null if
* not present
* @since 11
*/
public AlgorithmParameterSpec getKeyParams() {
return keyParams;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -26,11 +26,13 @@
package java.security.spec;
import java.math.BigInteger;
import java.util.Objects;
/**
* This class specifies an RSA multi-prime private key, as defined in the
* PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information
* values for efficiency.
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard
* using the Chinese Remainder Theorem (CRT) information values
* for efficiency.
*
* @author Valerie Peng
*
@ -57,34 +59,28 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
private final RSAOtherPrimeInfo[] otherPrimeInfo;
/**
* Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}
* given the modulus, publicExponent, privateExponent,
* primeP, primeQ, primeExponentP, primeExponentQ,
* crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1.
* Creates a new {@code RSAMultiPrimePrivateCrtKeySpec}.
*
* <p>Note that the contents of {@code otherPrimeInfo}
* are copied to protect against subsequent modification when
* constructing this object.
*
* @param modulus the modulus n.
* @param publicExponent the public exponent e.
* @param privateExponent the private exponent d.
* @param primeP the prime factor p of n.
* @param primeQ the prime factor q of n.
* @param primeExponentP this is d mod (p-1).
* @param primeExponentQ this is d mod (q-1).
* @param crtCoefficient the Chinese Remainder Theorem
* coefficient q-1 mod p.
* @param otherPrimeInfo triplets of the rest of primes, null can be
* specified if there are only two prime factors (p and q).
* @exception NullPointerException if any of the parameters, i.e.
* {@code modulus},
* {@code publicExponent}, {@code privateExponent},
* {@code primeP}, {@code primeQ},
* {@code primeExponentP}, {@code primeExponentQ},
* {@code crtCoefficient}, is null.
* @exception IllegalArgumentException if an empty, i.e. 0-length,
* {@code otherPrimeInfo} is specified.
* @param modulus the modulus n
* @param publicExponent the public exponent e
* @param privateExponent the private exponent d
* @param primeP the prime factor p of n
* @param primeQ the prime factor q of q
* @param primeExponentP this is d mod (p-1)
* @param primeExponentQ this is d mod (q-1)
* @param crtCoefficient the Chinese Remainder Theorem
* coefficient q-1 mod p
* @param otherPrimeInfo triplets of the rest of primes, null can be
* specified if there are only two prime factors
* (p and q)
* @throws NullPointerException if any of the specified parameters
* with the exception of {@code otherPrimeInfo} is null
* @throws IllegalArgumentException if an empty, i.e. 0-length,
* {@code otherPrimeInfo} is specified
*/
public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
BigInteger publicExponent,
@ -95,45 +91,67 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
BigInteger primeExponentQ,
BigInteger crtCoefficient,
RSAOtherPrimeInfo[] otherPrimeInfo) {
super(modulus, privateExponent);
if (modulus == null) {
throw new NullPointerException("the modulus parameter must be " +
"non-null");
}
if (publicExponent == null) {
throw new NullPointerException("the publicExponent parameter " +
"must be non-null");
}
if (privateExponent == null) {
throw new NullPointerException("the privateExponent parameter " +
"must be non-null");
}
if (primeP == null) {
throw new NullPointerException("the primeP parameter " +
"must be non-null");
}
if (primeQ == null) {
throw new NullPointerException("the primeQ parameter " +
"must be non-null");
}
if (primeExponentP == null) {
throw new NullPointerException("the primeExponentP parameter " +
"must be non-null");
}
if (primeExponentQ == null) {
throw new NullPointerException("the primeExponentQ parameter " +
"must be non-null");
}
if (crtCoefficient == null) {
throw new NullPointerException("the crtCoefficient parameter " +
"must be non-null");
}
this.publicExponent = publicExponent;
this.primeP = primeP;
this.primeQ = primeQ;
this.primeExponentP = primeExponentP;
this.primeExponentQ = primeExponentQ;
this.crtCoefficient = crtCoefficient;
this(modulus, publicExponent, privateExponent, primeP, primeQ,
primeExponentP, primeExponentQ, crtCoefficient, otherPrimeInfo,
null);
}
/**
* Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} with additional
* key parameters.
*
* <p>Note that the contents of {@code otherPrimeInfo}
* are copied to protect against subsequent modification when
* constructing this object.
*
* @param modulus the modulus n
* @param publicExponent the public exponent e
* @param privateExponent the private exponent d
* @param primeP the prime factor p of n
* @param primeQ the prime factor q of n
* @param primeExponentP this is d mod (p-1)
* @param primeExponentQ this is d mod (q-1)
* @param crtCoefficient the Chinese Remainder Theorem coefficient
* q-1 mod p
* @param otherPrimeInfo triplets of the rest of primes, null can be
* specified if there are only two prime factors
* (p and q)
* @param keyParams the parameters associated with key
* @throws NullPointerException if any of the specified parameters
* with the exception of {@code otherPrimeInfo} and {@code keyParams}
* is null
* @throws IllegalArgumentException if an empty, i.e. 0-length,
* {@code otherPrimeInfo} is specified
* @since 11
*/
public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
BigInteger publicExponent,
BigInteger privateExponent,
BigInteger primeP,
BigInteger primeQ,
BigInteger primeExponentP,
BigInteger primeExponentQ,
BigInteger crtCoefficient,
RSAOtherPrimeInfo[] otherPrimeInfo,
AlgorithmParameterSpec keyParams) {
super(modulus, privateExponent, keyParams);
Objects.requireNonNull(modulus,
"the modulus parameter must be non-null");
Objects.requireNonNull(privateExponent,
"the privateExponent parameter must be non-null");
this.publicExponent = Objects.requireNonNull(publicExponent,
"the publicExponent parameter must be non-null");
this.primeP = Objects.requireNonNull(primeP,
"the primeP parameter must be non-null");
this.primeQ = Objects.requireNonNull(primeQ,
"the primeQ parameter must be non-null");
this.primeExponentP = Objects.requireNonNull(primeExponentP,
"the primeExponentP parameter must be non-null");
this.primeExponentQ = Objects.requireNonNull(primeExponentQ,
"the primeExponentQ parameter must be non-null");
this.crtCoefficient = Objects.requireNonNull(crtCoefficient,
"the crtCoefficient parameter must be non-null");
if (otherPrimeInfo == null) {
this.otherPrimeInfo = null;
} else if (otherPrimeInfo.length == 0) {
@ -202,8 +220,8 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
* Returns a copy of the otherPrimeInfo or null if there are
* only two prime factors (p and q).
*
* @return the otherPrimeInfo. Returns a new array each
* time this method is called.
* @return the otherPrimeInfo. Returns a new array each time this method
* is called.
*/
public RSAOtherPrimeInfo[] getOtherPrimeInfo() {
if (otherPrimeInfo == null) return null;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -29,15 +29,16 @@ import java.math.BigInteger;
/**
* This class represents the triplet (prime, exponent, and coefficient)
* inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1.
* inside RSA's OtherPrimeInfo structure, as defined in the
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* The ASN.1 syntax of RSA's OtherPrimeInfo is as follows:
*
* <pre>
* OtherPrimeInfo ::= SEQUENCE {
* prime INTEGER,
* exponent INTEGER,
* coefficient INTEGER
* }
* prime INTEGER,
* exponent INTEGER,
* coefficient INTEGER
* }
*
* </pre>
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -28,9 +28,9 @@ package java.security.spec;
import java.math.BigInteger;
/**
* This class specifies an RSA private key, as defined in the PKCS#1
* standard, using the Chinese Remainder Theorem (CRT) information values for
* efficiency.
* This class specifies an RSA private key, as defined in the
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard,
* using the Chinese Remainder Theorem (CRT) information values for efficiency.
*
* @author Jan Luehe
* @since 1.2
@ -53,13 +53,8 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
private final BigInteger primeExponentQ;
private final BigInteger crtCoefficient;
/**
* Creates a new {@code RSAPrivateCrtKeySpec}
* given the modulus, publicExponent, privateExponent,
* primeP, primeQ, primeExponentP, primeExponentQ, and
* crtCoefficient as defined in PKCS#1.
* Creates a new {@code RSAPrivateCrtKeySpec}.
*
* @param modulus the modulus n
* @param publicExponent the public exponent e
@ -79,7 +74,36 @@ public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
BigInteger primeExponentP,
BigInteger primeExponentQ,
BigInteger crtCoefficient) {
super(modulus, privateExponent);
this(modulus, publicExponent, privateExponent, primeP, primeQ,
primeExponentP, primeExponentQ, crtCoefficient, null);
}
/**
* Creates a new {@code RSAPrivateCrtKeySpec} with additional
* key parameters.
*
* @param modulus the modulus n
* @param publicExponent the public exponent e
* @param privateExponent the private exponent d
* @param primeP the prime factor p of n
* @param primeQ the prime factor q of n
* @param primeExponentP this is d mod (p-1)
* @param primeExponentQ this is d mod (q-1)
* @param crtCoefficient the Chinese Remainder Theorem
* coefficient q-1 mod p
* @param keyParams the parameters associated with key
* @since 11
*/
public RSAPrivateCrtKeySpec(BigInteger modulus,
BigInteger publicExponent,
BigInteger privateExponent,
BigInteger primeP,
BigInteger primeQ,
BigInteger primeExponentP,
BigInteger primeExponentQ,
BigInteger crtCoefficient,
AlgorithmParameterSpec keyParams) {
super(modulus, privateExponent, keyParams);
this.publicExponent = publicExponent;
this.primeP = primeP;
this.primeQ = primeQ;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -44,8 +44,9 @@ import java.math.BigInteger;
public class RSAPrivateKeySpec implements KeySpec {
private BigInteger modulus;
private BigInteger privateExponent;
private final BigInteger modulus;
private final BigInteger privateExponent;
private final AlgorithmParameterSpec params;
/**
* Creates a new RSAPrivateKeySpec.
@ -54,8 +55,22 @@ public class RSAPrivateKeySpec implements KeySpec {
* @param privateExponent the private exponent
*/
public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) {
this(modulus, privateExponent, null);
}
/**
* Creates a new RSAPrivateKeySpec with additional key parameters.
*
* @param modulus the modulus
* @param privateExponent the private exponent
* @param params the parameters associated with this key, may be null
* @since 11
*/
public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent,
AlgorithmParameterSpec params) {
this.modulus = modulus;
this.privateExponent = privateExponent;
this.params = params;
}
/**
@ -75,4 +90,15 @@ public class RSAPrivateKeySpec implements KeySpec {
public BigInteger getPrivateExponent() {
return this.privateExponent;
}
/**
* Returns the parameters associated with this key, may be null if not
* present.
*
* @return the parameters associated with this key
* @since 11
*/
public AlgorithmParameterSpec getParams() {
return this.params;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -44,8 +44,9 @@ import java.math.BigInteger;
public class RSAPublicKeySpec implements KeySpec {
private BigInteger modulus;
private BigInteger publicExponent;
private final BigInteger modulus;
private final BigInteger publicExponent;
private final AlgorithmParameterSpec params;
/**
* Creates a new RSAPublicKeySpec.
@ -54,10 +55,25 @@ public class RSAPublicKeySpec implements KeySpec {
* @param publicExponent the public exponent
*/
public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) {
this(modulus, publicExponent, null);
}
/**
* Creates a new RSAPublicKeySpec with additional key parameters.
*
* @param modulus the modulus
* @param publicExponent the public exponent
* @param params the parameters associated with this key, may be null
* @since 11
*/
public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent,
AlgorithmParameterSpec params) {
this.modulus = modulus;
this.publicExponent = publicExponent;
this.params = params;
}
/**
* Returns the modulus.
*
@ -75,4 +91,16 @@ public class RSAPublicKeySpec implements KeySpec {
public BigInteger getPublicExponent() {
return this.publicExponent;
}
/**
* Returns the parameters associated with this key, may be null if not
* present.
*
* @return the parameters associated with this key
* @since 11
*/
public AlgorithmParameterSpec getParams() {
return this.params;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -42,7 +42,7 @@
* <h2>Package Specification</h2>
*
* <ul>
* <li>PKCS #1: RSA Encryption Standard, Version 1.5, November 1993</li>
* <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>PKCS #8: Private-Key Information Syntax Standard,
* Version 1.2, November 1993</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 186:

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -321,11 +321,15 @@ public class Cipher {
while (parser.hasMoreTokens() && count < 3) {
parts[count++] = parser.nextToken().trim();
}
if (count == 0 || count == 2 || parser.hasMoreTokens()) {
if (count == 0 || count == 2) {
throw new NoSuchAlgorithmException("Invalid transformation"
+ " format:" +
transformation);
}
// treats all subsequent tokens as part of padding
if (count == 3 && parser.hasMoreTokens()) {
parts[2] = parts[2] + parser.nextToken("\r\n");
}
} catch (NoSuchElementException e) {
throw new NoSuchAlgorithmException("Invalid transformation " +
"format:" + transformation);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -32,40 +32,53 @@ import java.security.spec.MGF1ParameterSpec;
/**
* This class specifies the set of parameters used with OAEP Padding,
* as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a>
* standard.
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
*
* Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
* RSAES-OAEP-params ::= SEQUENCE {
* hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
* maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
* pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
* pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
* }
* </pre>
* where
* <pre>
* HashAlgorithm ::= AlgorithmIdentifier {
* {OAEP-PSSDigestAlgorithms}
* }
* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
* PSourceAlgorithm ::= AlgorithmIdentifier {
* {PKCS1PSourceAlgorithms}
* }
*
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL },
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha224 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL }|
* { OID id-sha512-224 PARAMETERS NULL }|
* { OID id-sha512-256 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
* { OID id-mgf1 PARAMETERS HashAlgorithm },
* ... -- Allows for future expansion --
* }
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-pSpecified PARAMETERS OCTET STRING },
* { OID id-pSpecified PARAMETERS EncodingParameters },
* ... -- Allows for future expansion --
* }
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
* </pre>
* <p>Note: the OAEPParameterSpec.DEFAULT uses the following:
* <pre>
* message digest -- "SHA-1"
* mask generation function (mgf) -- "MGF1"
* parameters for mgf -- MGF1ParameterSpec.SHA1
* source of encoding input -- PSource.PSpecified.DEFAULT
* </pre>
*
* @see java.security.spec.MGF1ParameterSpec
* @see PSource

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -28,13 +28,19 @@ package javax.crypto.spec;
/**
* This class specifies the source for encoding input P in OAEP Padding,
* as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a>
* standard.
* <a href="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
* <pre>
* PSourceAlgorithm ::= AlgorithmIdentifier {
* {PKCS1PSourceAlgorithms}
* }
* </pre>
* where
* <pre>
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-pSpecified PARAMETERS OCTET STRING },
* { OID id-pSpecified PARAMETERS EncodingParameters },
* ... -- Allows for future expansion --
* }
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
* </pre>
* @author Valerie Peng
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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
@ -42,6 +42,7 @@
*
*
* <ul>
* <li>PKCS #1: RSA Cryptography Specifications, Version 2.2 (RFC 8017)</li>
* <li>PKCS #3: Diffie-Hellman Key-Agreement Standard, Version 1.4,
* November 1993.</li>
* <li>PKCS #5: Password-Based Encryption Standard, Version 1.5,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -28,20 +28,12 @@ package sun.security.pkcs;
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.CryptoPrimitive;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.Timestamp;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -62,6 +54,7 @@ import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension;
import sun.security.util.SignatureUtil;
/**
* A SignerInfo, as defined in PKCS#7's signedData type.
@ -453,30 +446,38 @@ public class SignerInfo implements DerEncoder {
}
Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selections occur when key is set
AlgorithmParameters ap =
digestEncryptionAlgorithmId.getParameters();
try {
SignatureUtil.specialSetParameter(sig, ap);
} catch (ProviderException | InvalidAlgorithmParameterException e) {
throw new SignatureException(e.getMessage(), e);
}
sig.update(dataSigned);
if (sig.verify(encryptedDigest)) {
return this;
}
} catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" +
e.getMessage());
} catch (InvalidKeyException e) {
throw new SignatureException("InvalidKey: " + e.getMessage());
}
return null;
}
/* Verify the content of the pkcs7 block. */
SignerInfo verify(PKCS7 block)
throws NoSuchAlgorithmException, SignatureException {
throws NoSuchAlgorithmException, SignatureException {
return verify(block, null);
}
public BigInteger getVersion() {
return version;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -31,11 +31,8 @@ import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.CertificateException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.PublicKey;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
@ -43,6 +40,8 @@ import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X509Key;
import sun.security.x509.X500Name;
import sun.security.util.SignatureUtil;
/**
* A PKCS #10 certificate request is created and sent to a Certificate
@ -169,12 +168,24 @@ public class PKCS10 {
try {
sigAlg = id.getName();
sig = Signature.getInstance(sigAlg);
sig.initVerify(subjectPublicKeyInfo);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selections occur when key is set
SignatureUtil.specialSetParameter(sig, id.getParameters());
sig.update(data);
if (!sig.verify(sigData))
if (!sig.verify(sigData)) {
throw new SignatureException("Invalid PKCS #10 signature");
}
} catch (InvalidKeyException e) {
throw new SignatureException("invalid key");
throw new SignatureException("Invalid key");
} catch (InvalidAlgorithmParameterException e) {
throw new SignatureException("Invalid signature parameters", e);
} catch (ProviderException e) {
throw new SignatureException("Error parsing signature parameters",
e.getCause());
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -33,6 +33,7 @@ import java.nio.ByteBuffer;
import java.security.*;
import java.security.SecureRandom;
import java.security.interfaces.*;
import java.security.spec.*;
import sun.security.util.Debug;
import sun.security.util.DerValue;
@ -370,11 +371,24 @@ abstract class DSA extends SignatureSpi {
throw new InvalidParameterException("No parameter accepted");
}
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameter accepted");
}
}
@Deprecated
protected Object engineGetParameter(String key) {
return null;
}
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
BigInteger k) {

View file

@ -0,0 +1,94 @@
/*
* 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. 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.rsa;
import java.security.*;
/**
* This class implements the MGF1 mask generation function defined in PKCS#1
* v2.2 B.2.1 (https://tools.ietf.org/html/rfc8017#appendix-B.2.1). A mask
* generation function takes an octet string of variable length and a
* desired output length as input and outputs an octet string of the
* desired length. MGF1 is a mask generation function based on a hash
* function, i.e. message digest algorithm.
*
* @since 11
*/
public final class MGF1 {
private final MessageDigest md;
/**
* Construct an instance of MGF1 based on the specified digest algorithm.
*/
MGF1(String mdAlgo) throws NoSuchAlgorithmException {
this.md = MessageDigest.getInstance(mdAlgo);
}
/**
* Using the specified seed bytes, generate the mask, xor the mask
* with the specified output buffer and store the result into the
* output buffer (essentially replaced in place).
*
* @param seed the buffer holding the seed bytes
* @param seedOfs the index of the seed bytes
* @param seedLen the length of the seed bytes to be used by MGF1
* @param maskLen the intended length of the generated mask
* @param out the output buffer holding the mask
* @param outOfs the index of the output buffer for the mask
*/
void generateAndXor(byte[] seed, int seedOfs, int seedLen, int maskLen,
byte[] out, int outOfs) throws RuntimeException {
byte[] C = new byte[4]; // 32 bit counter
byte[] digest = new byte[md.getDigestLength()];
while (maskLen > 0) {
md.update(seed, seedOfs, seedLen);
md.update(C);
try {
md.digest(digest, 0, digest.length);
} catch (DigestException e) {
// should never happen
throw new RuntimeException(e.toString());
}
for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
out[outOfs++] ^= digest[i++];
}
if (maskLen > 0) {
// increment counter
for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
// empty
}
}
}
}
/**
* Returns the name of this MGF1 instance, i.e. "MGF1" followed by the
* digest algorithm it based on.
*/
String getName() {
return "MGF1" + md.getAlgorithm();
}
}

View file

@ -0,0 +1,255 @@
/*
* 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. 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.rsa;
import java.io.*;
import sun.security.util.*;
import sun.security.x509.*;
import java.security.AlgorithmParametersSpi;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
import static java.security.spec.PSSParameterSpec.DEFAULT;
/**
* This class implements the PSS parameters used with the RSA
* signatures in PSS padding. Here is its ASN.1 definition:
* RSASSA-PSS-params ::= SEQUENCE {
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
* saltLength [2] INTEGER DEFAULT 20
* trailerField [3] TrailerField DEFAULT trailerFieldBC
* }
*
* @author Valerie Peng
*
*/
public final class PSSParameters extends AlgorithmParametersSpi {
private String mdName;
private MGF1ParameterSpec mgfSpec;
private int saltLength;
private int trailerField;
private static final ObjectIdentifier OID_MGF1 =
ObjectIdentifier.newInternal(new int[] {1,2,840,113549,1,1,8});
public PSSParameters() {
}
@Override
protected void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException {
if (!(paramSpec instanceof PSSParameterSpec)) {
throw new InvalidParameterSpecException
("Inappropriate parameter specification");
}
PSSParameterSpec spec = (PSSParameterSpec) paramSpec;
this.mdName = spec.getDigestAlgorithm();
String mgfName = spec.getMGFAlgorithm();
if (!mgfName.equalsIgnoreCase("MGF1")) {
throw new InvalidParameterSpecException("Unsupported mgf " +
mgfName + "; MGF1 only");
}
AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
if (!(mgfSpec instanceof MGF1ParameterSpec)) {
throw new InvalidParameterSpecException("Inappropriate mgf " +
"parameters; non-null MGF1ParameterSpec only");
}
this.mgfSpec = (MGF1ParameterSpec) mgfSpec;
this.saltLength = spec.getSaltLength();
this.trailerField = spec.getTrailerField();
}
@Override
protected void engineInit(byte[] encoded) throws IOException {
// first initialize with the DEFAULT values before
// retrieving from the encoding bytes
this.mdName = DEFAULT.getDigestAlgorithm();
this.mgfSpec = (MGF1ParameterSpec) DEFAULT.getMGFParameters();
this.saltLength = DEFAULT.getSaltLength();
this.trailerField = DEFAULT.getTrailerField();
DerInputStream der = new DerInputStream(encoded);
DerValue[] datum = der.getSequence(4);
for (DerValue d : datum) {
if (d.isContextSpecific((byte) 0x00)) {
// hash algid
this.mdName = AlgorithmId.parse
(d.data.getDerValue()).getName();
} else if (d.isContextSpecific((byte) 0x01)) {
// mgf algid
AlgorithmId val = AlgorithmId.parse(d.data.getDerValue());
if (!val.getOID().equals(OID_MGF1)) {
throw new IOException("Only MGF1 mgf is supported");
}
AlgorithmId params = AlgorithmId.parse(
new DerValue(val.getEncodedParams()));
String mgfDigestName = params.getName();
switch (mgfDigestName) {
case "SHA-1":
this.mgfSpec = MGF1ParameterSpec.SHA1;
break;
case "SHA-224":
this.mgfSpec = MGF1ParameterSpec.SHA224;
break;
case "SHA-256":
this.mgfSpec = MGF1ParameterSpec.SHA256;
break;
case "SHA-384":
this.mgfSpec = MGF1ParameterSpec.SHA384;
break;
case "SHA-512":
this.mgfSpec = MGF1ParameterSpec.SHA512;
break;
case "SHA-512/224":
this.mgfSpec = MGF1ParameterSpec.SHA512_224;
break;
case "SHA-512/256":
this.mgfSpec = MGF1ParameterSpec.SHA512_256;
break;
default:
throw new IOException
("Unrecognized message digest algorithm " +
mgfDigestName);
}
} else if (d.isContextSpecific((byte) 0x02)) {
// salt length
this.saltLength = d.data.getDerValue().getInteger();
if (this.saltLength < 0) {
throw new IOException("Negative value for saltLength");
}
} else if (d.isContextSpecific((byte) 0x03)) {
// trailer field
this.trailerField = d.data.getDerValue().getInteger();
if (this.trailerField != 1) {
throw new IOException("Unsupported trailerField value " +
this.trailerField);
}
} else {
throw new IOException("Invalid encoded PSSParameters");
}
}
}
@Override
protected void engineInit(byte[] encoded, String decodingMethod)
throws IOException {
if ((decodingMethod != null) &&
(!decodingMethod.equalsIgnoreCase("ASN.1"))) {
throw new IllegalArgumentException("Only support ASN.1 format");
}
engineInit(encoded);
}
@Override
protected <T extends AlgorithmParameterSpec>
T engineGetParameterSpec(Class<T> paramSpec)
throws InvalidParameterSpecException {
if (PSSParameterSpec.class.isAssignableFrom(paramSpec)) {
return paramSpec.cast(
new PSSParameterSpec(mdName, "MGF1", mgfSpec,
saltLength, trailerField));
} else {
throw new InvalidParameterSpecException
("Inappropriate parameter specification");
}
}
@Override
protected byte[] engineGetEncoded() throws IOException {
DerOutputStream tmp = new DerOutputStream();
DerOutputStream tmp2, tmp3;
// MD
AlgorithmId mdAlgId;
try {
mdAlgId = AlgorithmId.get(mdName);
} catch (NoSuchAlgorithmException nsae) {
throw new IOException("AlgorithmId " + mdName +
" impl not found");
}
tmp2 = new DerOutputStream();
mdAlgId.derEncode(tmp2);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0),
tmp2);
// MGF
tmp2 = new DerOutputStream();
tmp2.putOID(OID_MGF1);
AlgorithmId mgfDigestId;
try {
mgfDigestId = AlgorithmId.get(mgfSpec.getDigestAlgorithm());
} catch (NoSuchAlgorithmException nase) {
throw new IOException("AlgorithmId " +
mgfSpec.getDigestAlgorithm() + " impl not found");
}
mgfDigestId.encode(tmp2);
tmp3 = new DerOutputStream();
tmp3.write(DerValue.tag_Sequence, tmp2);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)1),
tmp3);
// SaltLength
tmp2 = new DerOutputStream();
tmp2.putInteger(saltLength);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)2),
tmp2);
// TrailerField
tmp2 = new DerOutputStream();
tmp2.putInteger(trailerField);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)3),
tmp2);
// Put all together under a SEQUENCE tag
DerOutputStream out = new DerOutputStream();
out.write(DerValue.tag_Sequence, tmp);
return out.toByteArray();
}
@Override
protected byte[] engineGetEncoded(String encMethod) throws IOException {
if ((encMethod != null) &&
(!encMethod.equalsIgnoreCase("ASN.1"))) {
throw new IllegalArgumentException("Only support ASN.1 format");
}
return engineGetEncoded();
}
@Override
protected String engineToString() {
StringBuilder sb = new StringBuilder();
sb.append("MD: " + mdName + "\n")
.append("MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n")
.append("SaltLength: " + saltLength + "\n")
.append("TrailerField: " + trailerField + "\n");
return sb.toString();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -32,10 +32,15 @@ import java.security.interfaces.*;
import java.security.spec.*;
import sun.security.action.GetPropertyAction;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/**
* KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
* and getAlgorithm() must return "RSA". For such keys, it supports conversion
* KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
* Keys must be instances of PublicKey or PrivateKey
* and getAlgorithm() must return a value which matches the type which are
* specified during construction time of the KeyFactory object.
* For such keys, it supports conversion
* between the following:
*
* For public keys:
@ -58,21 +63,21 @@ import sun.security.action.GetPropertyAction;
* @since 1.5
* @author Andreas Sterbenz
*/
public final class RSAKeyFactory extends KeyFactorySpi {
public class RSAKeyFactory extends KeyFactorySpi {
private static final Class<?> rsaPublicKeySpecClass =
RSAPublicKeySpec.class;
private static final Class<?> rsaPrivateKeySpecClass =
RSAPrivateKeySpec.class;
private static final Class<?> rsaPrivateCrtKeySpecClass =
RSAPrivateCrtKeySpec.class;
private static final Class<?> x509KeySpecClass = X509EncodedKeySpec.class;
private static final Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
private static final Class<?> RSA_PUB_KEYSPEC_CLS = RSAPublicKeySpec.class;
private static final Class<?> RSA_PRIV_KEYSPEC_CLS =
RSAPrivateKeySpec.class;
private static final Class<?> RSA_PRIVCRT_KEYSPEC_CLS =
RSAPrivateCrtKeySpec.class;
private static final Class<?> X509_KEYSPEC_CLS = X509EncodedKeySpec.class;
private static final Class<?> PKCS8_KEYSPEC_CLS = PKCS8EncodedKeySpec.class;
public static final int MIN_MODLEN = 512;
public static final int MAX_MODLEN = 16384;
private final KeyType type;
/*
* If the modulus length is above this value, restrict the size of
* the exponent to something that can be reasonably computed. We
@ -87,11 +92,18 @@ public final class RSAKeyFactory extends KeyFactorySpi {
"true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty(
"sun.security.rsa.restrictRSAExponent", "true"));
// instance used for static translateKey();
private static final RSAKeyFactory INSTANCE = new RSAKeyFactory();
static RSAKeyFactory getInstance(KeyType type) {
return new RSAKeyFactory(type);
}
public RSAKeyFactory() {
// empty
// Internal utility method for checking key algorithm
private static void checkKeyAlgo(Key key, String expectedAlg)
throws InvalidKeyException {
String keyAlg = key.getAlgorithm();
if (!(keyAlg.equalsIgnoreCase(expectedAlg))) {
throw new InvalidKeyException("Expected a " + expectedAlg
+ " key, but got " + keyAlg);
}
}
/**
@ -107,7 +119,14 @@ public final class RSAKeyFactory extends KeyFactorySpi {
(key instanceof RSAPublicKeyImpl)) {
return (RSAKey)key;
} else {
return (RSAKey)INSTANCE.engineTranslateKey(key);
try {
String keyAlgo = key.getAlgorithm();
KeyType type = KeyType.lookup(keyAlgo);
RSAKeyFactory kf = RSAKeyFactory.getInstance(type);
return (RSAKey) kf.engineTranslateKey(key);
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
}
}
@ -171,6 +190,15 @@ public final class RSAKeyFactory extends KeyFactorySpi {
}
}
// disallowed as KeyType is required
private RSAKeyFactory() {
this.type = KeyType.RSA;
}
public RSAKeyFactory(KeyType type) {
this.type = type;
}
/**
* Translate an RSA key into a SunRsaSign RSA key. If conversion is
* not possible, throw an InvalidKeyException.
@ -180,9 +208,14 @@ public final class RSAKeyFactory extends KeyFactorySpi {
if (key == null) {
throw new InvalidKeyException("Key must not be null");
}
String keyAlg = key.getAlgorithm();
if (keyAlg.equals("RSA") == false) {
throw new InvalidKeyException("Not an RSA key: " + keyAlg);
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(key, type.keyAlgo());
// no translation needed if the key is already our own impl
if ((key instanceof RSAPrivateKeyImpl) ||
(key instanceof RSAPrivateCrtKeyImpl) ||
(key instanceof RSAPublicKeyImpl)) {
return key;
}
if (key instanceof PublicKey) {
return translatePublicKey((PublicKey)key);
@ -221,22 +254,22 @@ public final class RSAKeyFactory extends KeyFactorySpi {
private PublicKey translatePublicKey(PublicKey key)
throws InvalidKeyException {
if (key instanceof RSAPublicKey) {
if (key instanceof RSAPublicKeyImpl) {
return key;
}
RSAPublicKey rsaKey = (RSAPublicKey)key;
try {
return new RSAPublicKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(),
rsaKey.getPublicExponent()
);
} catch (RuntimeException e) {
rsaKey.getPublicExponent());
} catch (ProviderException e) {
// catch providers that incorrectly implement RSAPublicKey
throw new InvalidKeyException("Invalid key", e);
}
} else if ("X.509".equals(key.getFormat())) {
byte[] encoded = key.getEncoded();
return new RSAPublicKeyImpl(encoded);
RSAPublicKey translated = new RSAPublicKeyImpl(encoded);
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(translated, type.keyAlgo());
return translated;
} else {
throw new InvalidKeyException("Public keys must be instance "
+ "of RSAPublicKey or have X.509 encoding");
@ -247,12 +280,10 @@ public final class RSAKeyFactory extends KeyFactorySpi {
private PrivateKey translatePrivateKey(PrivateKey key)
throws InvalidKeyException {
if (key instanceof RSAPrivateCrtKey) {
if (key instanceof RSAPrivateCrtKeyImpl) {
return key;
}
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
try {
return new RSAPrivateCrtKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(),
rsaKey.getPublicExponent(),
rsaKey.getPrivateExponent(),
@ -262,27 +293,28 @@ public final class RSAKeyFactory extends KeyFactorySpi {
rsaKey.getPrimeExponentQ(),
rsaKey.getCrtCoefficient()
);
} catch (RuntimeException e) {
} catch (ProviderException e) {
// catch providers that incorrectly implement RSAPrivateCrtKey
throw new InvalidKeyException("Invalid key", e);
}
} else if (key instanceof RSAPrivateKey) {
if (key instanceof RSAPrivateKeyImpl) {
return key;
}
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
try {
return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
rsaKey.getModulus(),
rsaKey.getPrivateExponent()
);
} catch (RuntimeException e) {
} catch (ProviderException e) {
// catch providers that incorrectly implement RSAPrivateKey
throw new InvalidKeyException("Invalid key", e);
}
} else if ("PKCS#8".equals(key.getFormat())) {
byte[] encoded = key.getEncoded();
return RSAPrivateCrtKeyImpl.newKey(encoded);
RSAPrivateKey translated = RSAPrivateCrtKeyImpl.newKey(encoded);
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(translated, type.keyAlgo());
return translated;
} else {
throw new InvalidKeyException("Private keys must be instance "
+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
@ -294,13 +326,21 @@ public final class RSAKeyFactory extends KeyFactorySpi {
throws GeneralSecurityException {
if (keySpec instanceof X509EncodedKeySpec) {
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
return new RSAPublicKeyImpl(x509Spec.getEncoded());
RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(generated, type.keyAlgo());
return generated;
} else if (keySpec instanceof RSAPublicKeySpec) {
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
return new RSAPublicKeyImpl(
rsaSpec.getModulus(),
rsaSpec.getPublicExponent()
);
try {
return new RSAPublicKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
rsaSpec.getModulus(),
rsaSpec.getPublicExponent()
);
} catch (ProviderException e) {
throw new InvalidKeySpecException(e);
}
} else {
throw new InvalidKeySpecException("Only RSAPublicKeySpec "
+ "and X509EncodedKeySpec supported for RSA public keys");
@ -312,25 +352,38 @@ public final class RSAKeyFactory extends KeyFactorySpi {
throws GeneralSecurityException {
if (keySpec instanceof PKCS8EncodedKeySpec) {
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(generated, type.keyAlgo());
return generated;
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
return new RSAPrivateCrtKeyImpl(
rsaSpec.getModulus(),
rsaSpec.getPublicExponent(),
rsaSpec.getPrivateExponent(),
rsaSpec.getPrimeP(),
rsaSpec.getPrimeQ(),
rsaSpec.getPrimeExponentP(),
rsaSpec.getPrimeExponentQ(),
rsaSpec.getCrtCoefficient()
);
try {
return new RSAPrivateCrtKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
rsaSpec.getModulus(),
rsaSpec.getPublicExponent(),
rsaSpec.getPrivateExponent(),
rsaSpec.getPrimeP(),
rsaSpec.getPrimeQ(),
rsaSpec.getPrimeExponentP(),
rsaSpec.getPrimeExponentQ(),
rsaSpec.getCrtCoefficient()
);
} catch (ProviderException e) {
throw new InvalidKeySpecException(e);
}
} else if (keySpec instanceof RSAPrivateKeySpec) {
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
return new RSAPrivateKeyImpl(
rsaSpec.getModulus(),
rsaSpec.getPrivateExponent()
);
try {
return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
rsaSpec.getModulus(),
rsaSpec.getPrivateExponent()
);
} catch (ProviderException e) {
throw new InvalidKeySpecException(e);
}
} else {
throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+ "and PKCS8EncodedKeySpec supported for RSA private keys");
@ -349,12 +402,13 @@ public final class RSAKeyFactory extends KeyFactorySpi {
}
if (key instanceof RSAPublicKey) {
RSAPublicKey rsaKey = (RSAPublicKey)key;
if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) {
if (RSA_PUB_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new RSAPublicKeySpec(
rsaKey.getModulus(),
rsaKey.getPublicExponent()
rsaKey.getPublicExponent(),
rsaKey.getParams()
));
} else if (x509KeySpecClass.isAssignableFrom(keySpec)) {
} else if (X509_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new X509EncodedKeySpec(key.getEncoded()));
} else {
throw new InvalidKeySpecException
@ -362,9 +416,9 @@ public final class RSAKeyFactory extends KeyFactorySpi {
+ "X509EncodedKeySpec for RSA public keys");
}
} else if (key instanceof RSAPrivateKey) {
if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) {
if (PKCS8_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded()));
} else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) {
} else if (RSA_PRIVCRT_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
if (key instanceof RSAPrivateCrtKey) {
RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key;
return keySpec.cast(new RSAPrivateCrtKeySpec(
@ -375,17 +429,19 @@ public final class RSAKeyFactory extends KeyFactorySpi {
crtKey.getPrimeQ(),
crtKey.getPrimeExponentP(),
crtKey.getPrimeExponentQ(),
crtKey.getCrtCoefficient()
crtKey.getCrtCoefficient(),
crtKey.getParams()
));
} else {
throw new InvalidKeySpecException
("RSAPrivateCrtKeySpec can only be used with CRT keys");
}
} else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) {
} else if (RSA_PRIV_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
return keySpec.cast(new RSAPrivateKeySpec(
rsaKey.getModulus(),
rsaKey.getPrivateExponent()
rsaKey.getPrivateExponent(),
rsaKey.getParams()
));
} else {
throw new InvalidKeySpecException
@ -397,4 +453,16 @@ public final class RSAKeyFactory extends KeyFactorySpi {
throw new InvalidKeySpecException("Neither public nor private key");
}
}
public static final class Legacy extends RSAKeyFactory {
public Legacy() {
super(KeyType.RSA);
}
}
public static final class PSS extends RSAKeyFactory {
public PSS() {
super(KeyType.PSS);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -33,6 +33,9 @@ import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/**
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@ -43,7 +46,7 @@ import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
* @since 1.5
* @author Andreas Sterbenz
*/
public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// public exponent to use
private BigInteger publicExponent;
@ -51,35 +54,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
private int keySize;
private final KeyType type;
private AlgorithmId rsaId;
// PRNG to use
private SecureRandom random;
public RSAKeyPairGenerator() {
RSAKeyPairGenerator(KeyType type, int defKeySize) {
this.type = type;
// initialize to default in case the app does not call initialize()
initialize(DEF_RSA_KEY_SIZE, null);
initialize(defKeySize, null);
}
// initialize the generator. See JCA doc
public void initialize(int keySize, SecureRandom random) {
// do not allow unreasonably small or large key sizes,
// probably user error
try {
RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4,
512, 64 * 1024);
} catch (InvalidKeyException e) {
throw new InvalidParameterException(e.getMessage());
initialize(new RSAKeyGenParameterSpec(keySize,
RSAKeyGenParameterSpec.F4), null);
} catch (InvalidAlgorithmParameterException iape) {
throw new InvalidParameterException(iape.getMessage());
}
this.keySize = keySize;
this.random = random;
this.publicExponent = RSAKeyGenParameterSpec.F4;
}
// second initialize method. See JCA doc.
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException {
if (params instanceof RSAKeyGenParameterSpec == false) {
throw new InvalidAlgorithmParameterException
("Params must be instance of RSAKeyGenParameterSpec");
@ -88,6 +87,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
int tmpKeySize = rsaSpec.getKeysize();
BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams();
if (tmpPublicExponent == null) {
tmpPublicExponent = RSAKeyGenParameterSpec.F4;
@ -111,6 +111,13 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
"Invalid key sizes", e);
}
try {
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
} catch (ProviderException e) {
throw new InvalidAlgorithmParameterException(
"Invalid key parameters", e);
}
this.keySize = tmpKeySize;
this.publicExponent = tmpPublicExponent;
this.random = random;
@ -166,9 +173,9 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
BigInteger coeff = q.modInverse(p);
try {
PublicKey publicKey = new RSAPublicKeyImpl(n, e);
PrivateKey privateKey =
new RSAPrivateCrtKeyImpl(n, e, d, p, q, pe, qe, coeff);
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
rsaId, n, e, d, p, q, pe, qe, coeff);
return new KeyPair(publicKey, privateKey);
} catch (InvalidKeyException exc) {
// invalid key exception only thrown for keys < 512 bit,
@ -178,4 +185,15 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
}
}
public static final class Legacy extends RSAKeyPairGenerator {
public Legacy() {
super(KeyType.RSA, DEF_RSA_KEY_SIZE);
}
}
public static final class PSS extends RSAKeyPairGenerator {
public PSS() {
super(KeyType.PSS, DEF_RSASSA_PSS_KEY_SIZE);
}
}
}

View file

@ -0,0 +1,619 @@
/*
* 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. 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.rsa;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.PSSParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.interfaces.*;
import java.util.Arrays;
import java.util.Hashtable;
import sun.security.util.*;
import sun.security.jca.JCAUtil;
/**
* PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms.
* RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm,
* and salt length values through the required signature PSS parameters.
* We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and
* SHA-512/256 message digest algorithms and MGF1 mask generation function.
*
* @since 11
*/
public class RSAPSSSignature extends SignatureSpi {
private static final boolean DEBUG = false;
// utility method for comparing digest algorithms
// NOTE that first argument is assumed to be standard digest name
private boolean isDigestEqual(String stdAlg, String givenAlg) {
if (stdAlg == null || givenAlg == null) return false;
if (givenAlg.indexOf("-") != -1) {
return stdAlg.equalsIgnoreCase(givenAlg);
} else {
if (stdAlg.equals("SHA-1")) {
return (givenAlg.equalsIgnoreCase("SHA")
|| givenAlg.equalsIgnoreCase("SHA1"));
} else {
StringBuilder sb = new StringBuilder(givenAlg);
// case-insensitive check
if (givenAlg.regionMatches(true, 0, "SHA", 0, 3)) {
givenAlg = sb.insert(3, "-").toString();
return stdAlg.equalsIgnoreCase(givenAlg);
} else {
throw new ProviderException("Unsupported digest algorithm "
+ givenAlg);
}
}
}
}
private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8];
private static final Hashtable<String, Integer> DIGEST_LENGTHS =
new Hashtable<String, Integer>();
static {
DIGEST_LENGTHS.put("SHA-1", 20);
DIGEST_LENGTHS.put("SHA", 20);
DIGEST_LENGTHS.put("SHA1", 20);
DIGEST_LENGTHS.put("SHA-224", 28);
DIGEST_LENGTHS.put("SHA224", 28);
DIGEST_LENGTHS.put("SHA-256", 32);
DIGEST_LENGTHS.put("SHA256", 32);
DIGEST_LENGTHS.put("SHA-384", 48);
DIGEST_LENGTHS.put("SHA384", 48);
DIGEST_LENGTHS.put("SHA-512", 64);
DIGEST_LENGTHS.put("SHA512", 64);
DIGEST_LENGTHS.put("SHA-512/224", 28);
DIGEST_LENGTHS.put("SHA512/224", 28);
DIGEST_LENGTHS.put("SHA-512/256", 32);
DIGEST_LENGTHS.put("SHA512/256", 32);
}
// message digest implementation we use for hashing the data
private MessageDigest md;
// flag indicating whether the digest is reset
private boolean digestReset = true;
// private key, if initialized for signing
private RSAPrivateKey privKey = null;
// public key, if initialized for verifying
private RSAPublicKey pubKey = null;
// PSS parameters from signatures and keys respectively
private PSSParameterSpec sigParams = null; // required for PSS signatures
// PRNG used to generate salt bytes if none given
private SecureRandom random;
/**
* Construct a new RSAPSSSignatur with arbitrary digest algorithm
*/
public RSAPSSSignature() {
this.md = null;
}
// initialize for verification. See JCA doc
@Override
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
if (!(publicKey instanceof RSAPublicKey)) {
throw new InvalidKeyException("key must be RSAPublicKey");
}
this.pubKey = (RSAPublicKey) isValid((RSAKey)publicKey);
this.privKey = null;
}
// initialize for signing. See JCA doc
@Override
protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException {
engineInitSign(privateKey, null);
}
// initialize for signing. See JCA doc
@Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
if (!(privateKey instanceof RSAPrivateKey)) {
throw new InvalidKeyException("key must be RSAPrivateKey");
}
this.privKey = (RSAPrivateKey) isValid((RSAKey)privateKey);
this.pubKey = null;
this.random =
(random == null? JCAUtil.getSecureRandom() : random);
}
/**
* Utility method for checking the key PSS parameters against signature
* PSS parameters.
* Returns false if any of the digest/MGF algorithms and trailerField
* values does not match or if the salt length in key parameters is
* larger than the value in signature parameters.
*/
private static boolean isCompatible(AlgorithmParameterSpec keyParams,
PSSParameterSpec sigParams) {
if (keyParams == null) {
// key with null PSS parameters means no restriction
return true;
}
if (!(keyParams instanceof PSSParameterSpec)) {
return false;
}
// nothing to compare yet, defer the check to when sigParams is set
if (sigParams == null) {
return true;
}
PSSParameterSpec pssKeyParams = (PSSParameterSpec) keyParams;
// first check the salt length requirement
if (pssKeyParams.getSaltLength() > sigParams.getSaltLength()) {
return false;
}
// compare equality of the rest of fields based on DER encoding
PSSParameterSpec keyParams2 =
new PSSParameterSpec(pssKeyParams.getDigestAlgorithm(),
pssKeyParams.getMGFAlgorithm(),
pssKeyParams.getMGFParameters(),
sigParams.getSaltLength(),
pssKeyParams.getTrailerField());
PSSParameters ap = new PSSParameters();
// skip the JCA overhead
try {
ap.engineInit(keyParams2);
byte[] encoded = ap.engineGetEncoded();
ap.engineInit(sigParams);
byte[] encoded2 = ap.engineGetEncoded();
return Arrays.equals(encoded, encoded2);
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
return false;
}
}
/**
* Validate the specified RSAKey and its associated parameters against
* internal signature parameters.
*/
private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException {
try {
AlgorithmParameterSpec keyParams = rsaKey.getParams();
// validate key parameters
if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
throw new InvalidKeyException
("Key contains incompatible PSS parameter values");
}
// validate key length
if (this.sigParams != null) {
Integer hLen =
DIGEST_LENGTHS.get(this.sigParams.getDigestAlgorithm());
if (hLen == null) {
throw new ProviderException("Unsupported digest algo: " +
this.sigParams.getDigestAlgorithm());
}
checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength());
}
return rsaKey;
} catch (SignatureException e) {
throw new InvalidKeyException(e);
}
}
/**
* Validate the specified Signature PSS parameters.
*/
private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
throws InvalidAlgorithmParameterException {
if (p == null) {
throw new InvalidAlgorithmParameterException
("Parameters cannot be null");
}
if (!(p instanceof PSSParameterSpec)) {
throw new InvalidAlgorithmParameterException
("parameters must be type PSSParameterSpec");
}
// no need to validate again if same as current signature parameters
PSSParameterSpec params = (PSSParameterSpec) p;
if (params == this.sigParams) return params;
RSAKey key = (this.privKey == null? this.pubKey : this.privKey);
// check against keyParams if set
if (key != null) {
if (!isCompatible(key.getParams(), params)) {
throw new InvalidAlgorithmParameterException
("Signature parameters does not match key parameters");
}
}
// now sanity check the parameter values
if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
throw new InvalidAlgorithmParameterException("Only supports MGF1");
}
if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
throw new InvalidAlgorithmParameterException
("Only supports TrailerFieldBC(1)");
}
String digestAlgo = params.getDigestAlgorithm();
// check key length again
if (key != null) {
try {
int hLen = DIGEST_LENGTHS.get(digestAlgo);
checkKeyLength(key, hLen, params.getSaltLength());
} catch (SignatureException e) {
throw new InvalidAlgorithmParameterException(e);
}
}
return params;
}
/**
* Ensure the object is initialized with key and parameters and
* reset digest
*/
private void ensureInit() throws SignatureException {
RSAKey key = (this.privKey == null? this.pubKey : this.privKey);
if (key == null) {
throw new SignatureException("Missing key");
}
if (this.sigParams == null) {
// Parameters are required for signature verification
throw new SignatureException
("Parameters required for RSASSA-PSS signatures");
}
}
/**
* Utility method for checking key length against digest length and
* salt length
*/
private static void checkKeyLength(RSAKey key, int digestLen,
int saltLen) throws SignatureException {
if (key != null) {
int keyLength = getKeyLengthInBits(key) >> 3;
int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2);
if (keyLength < minLength) {
throw new SignatureException
("Key is too short, need min " + minLength);
}
}
}
/**
* Reset the message digest if it is not already reset.
*/
private void resetDigest() {
if (digestReset == false) {
this.md.reset();
digestReset = true;
}
}
/**
* Return the message digest value.
*/
private byte[] getDigestValue() {
digestReset = true;
return this.md.digest();
}
// update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(byte b) throws SignatureException {
ensureInit();
this.md.update(b);
digestReset = false;
}
// update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(byte[] b, int off, int len)
throws SignatureException {
ensureInit();
this.md.update(b, off, len);
digestReset = false;
}
// update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(ByteBuffer b) {
try {
ensureInit();
} catch (SignatureException se) {
// hack for working around API bug
throw new RuntimeException(se.getMessage());
}
this.md.update(b);
digestReset = false;
}
// sign the data and return the signature. See JCA doc
@Override
protected byte[] engineSign() throws SignatureException {
ensureInit();
byte[] mHash = getDigestValue();
try {
byte[] encoded = encodeSignature(mHash);
byte[] encrypted = RSACore.rsa(encoded, privKey, true);
return encrypted;
} catch (GeneralSecurityException e) {
throw new SignatureException("Could not sign data", e);
} catch (IOException e) {
throw new SignatureException("Could not encode data", e);
}
}
// verify the data and return the result. See JCA doc
// should be reset to the state after engineInitVerify call.
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
ensureInit();
try {
if (sigBytes.length != RSACore.getByteLength(this.pubKey)) {
throw new SignatureException
("Signature length not correct: got "
+ sigBytes.length + " but was expecting "
+ RSACore.getByteLength(this.pubKey));
}
byte[] mHash = getDigestValue();
byte[] decrypted = RSACore.rsa(sigBytes, this.pubKey);
return decodeSignature(mHash, decrypted);
} catch (javax.crypto.BadPaddingException e) {
// occurs if the app has used the wrong RSA public key
// or if sigBytes is invalid
// return false rather than propagating the exception for
// compatibility/ease of use
return false;
} catch (IOException e) {
throw new SignatureException("Signature encoding error", e);
} finally {
resetDigest();
}
}
// return the modulus length in bits
private static int getKeyLengthInBits(RSAKey k) {
if (k != null) {
return k.getModulus().bitLength();
}
return -1;
}
/**
* Encode the digest 'mHash', return the to-be-signed data.
* Also used by the PKCS#11 provider.
*/
private byte[] encodeSignature(byte[] mHash)
throws IOException, DigestException {
AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
String mgfDigestAlgo;
if (mgfParams != null) {
mgfDigestAlgo =
((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
} else {
mgfDigestAlgo = this.md.getAlgorithm();
}
try {
int emBits = getKeyLengthInBits(this.privKey) - 1;
int emLen =(emBits + 7) >> 3;
int hLen = this.md.getDigestLength();
int dbLen = emLen - hLen - 1;
int sLen = this.sigParams.getSaltLength();
// maps DB into the corresponding region of EM and
// stores its bytes directly into EM
byte[] em = new byte[emLen];
// step7 and some of step8
em[dbLen - sLen - 1] = (byte) 1; // set DB's padding2 into EM
em[em.length - 1] = (byte) 0xBC; // set trailer field of EM
if (!digestReset) {
throw new ProviderException("Digest should be reset");
}
// step5: generates M' using padding1, mHash, and salt
this.md.update(EIGHT_BYTES_OF_ZEROS);
digestReset = false; // mark digest as it now has data
this.md.update(mHash);
if (sLen != 0) {
// step4: generate random salt
byte[] salt = new byte[sLen];
this.random.nextBytes(salt);
this.md.update(salt);
// step8: set DB's salt into EM
System.arraycopy(salt, 0, em, dbLen - sLen, sLen);
}
// step6: generate H using M'
this.md.digest(em, dbLen, hLen); // set H field of EM
digestReset = true;
// step7 and 8 are already covered by the code which setting up
// EM as above
// step9 and 10: feed H into MGF and xor with DB in EM
MGF1 mgf1 = new MGF1(mgfDigestAlgo);
mgf1.generateAndXor(em, dbLen, hLen, dbLen, em, 0);
// step11: set the leftmost (8emLen - emBits) bits of the leftmost
// octet to 0
int numZeroBits = (emLen << 3) - emBits;
if (numZeroBits != 0) {
byte MASK = (byte) (0xff >>> numZeroBits);
em[0] = (byte) (em[0] & MASK);
}
// step12: em should now holds maskedDB || hash h || 0xBC
return em;
} catch (NoSuchAlgorithmException e) {
throw new IOException(e.toString());
}
}
/**
* Decode the signature data. Verify that the object identifier matches
* and return the message digest.
*/
private boolean decodeSignature(byte[] mHash, byte[] em)
throws IOException {
int hLen = mHash.length;
int sLen = this.sigParams.getSaltLength();
int emLen = em.length;
int emBits = getKeyLengthInBits(this.pubKey) - 1;
// step3
if (emLen < (hLen + sLen + 2)) {
return false;
}
// step4
if (em[emLen - 1] != (byte) 0xBC) {
return false;
}
// step6: check if the leftmost (8emLen - emBits) bits of the leftmost
// octet are 0
int numZeroBits = (emLen << 3) - emBits;
if (numZeroBits != 0) {
byte MASK = (byte) (0xff << (8 - numZeroBits));
if ((em[0] & MASK) != 0) {
return false;
}
}
String mgfDigestAlgo;
AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
if (mgfParams != null) {
mgfDigestAlgo =
((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
} else {
mgfDigestAlgo = this.md.getAlgorithm();
}
// step 7 and 8
int dbLen = emLen - hLen - 1;
try {
MGF1 mgf1 = new MGF1(mgfDigestAlgo);
mgf1.generateAndXor(em, dbLen, hLen, dbLen, em, 0);
} catch (NoSuchAlgorithmException nsae) {
throw new IOException(nsae.toString());
}
// step9: set the leftmost (8emLen - emBits) bits of the leftmost
// octet to 0
if (numZeroBits != 0) {
byte MASK = (byte) (0xff >>> numZeroBits);
em[0] = (byte) (em[0] & MASK);
}
// step10
int i = 0;
for (; i < dbLen - sLen - 1; i++) {
if (em[i] != 0) {
return false;
}
}
if (em[i] != 0x01) {
return false;
}
// step12 and 13
this.md.update(EIGHT_BYTES_OF_ZEROS);
digestReset = false;
this.md.update(mHash);
if (sLen > 0) {
this.md.update(em, (dbLen - sLen), sLen);
}
byte[] digest2 = this.md.digest();
digestReset = true;
// step14
byte[] digestInEM = Arrays.copyOfRange(em, dbLen, emLen - 1);
return MessageDigest.isEqual(digest2, digestInEM);
}
// set parameter, not supported. See JCA doc
@Deprecated
@Override
protected void engineSetParameter(String param, Object value)
throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported");
}
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
this.sigParams = validateSigParams(params);
// disallow changing parameters when digest has been used
if (!digestReset) {
throw new ProviderException
("Cannot set parameters during operations");
}
String newHashAlg = this.sigParams.getDigestAlgorithm();
// re-allocate md if not yet assigned or algorithm changed
if ((this.md == null) ||
!(this.md.getAlgorithm().equalsIgnoreCase(newHashAlg))) {
try {
this.md = MessageDigest.getInstance(newHashAlg);
} catch (NoSuchAlgorithmException nsae) {
// should not happen as we pick default digest algorithm
throw new InvalidAlgorithmParameterException
("Unsupported digest algorithm " +
newHashAlg, nsae);
}
}
}
// get parameter, not supported. See JCA doc
@Deprecated
@Override
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
}
@Override
protected AlgorithmParameters engineGetParameters() {
if (this.sigParams == null) {
throw new ProviderException("Missing required PSS parameters");
}
try {
AlgorithmParameters ap =
AlgorithmParameters.getInstance("RSASSA-PSS");
ap.init(this.sigParams);
return ap;
} catch (GeneralSecurityException gse) {
throw new ProviderException(gse.getMessage());
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -39,16 +39,13 @@ import sun.security.jca.JCAUtil;
/**
* RSA padding and unpadding.
*
* The various PKCS#1 versions can be found in the EMC/RSA Labs
* web site, which is currently:
* The various PKCS#1 versions can be found in the IETF RFCs
* tracking the corresponding PKCS#1 standards.
*
* http://www.emc.com/emc-plus/rsa-labs/index.htm
*
* or in the IETF RFCs derived from the above PKCS#1 standards.
*
* RFC 2313: v1.5
* RFC 2437: v2.0
* RFC 3447: v2.1
* RFC 2313: PKCS#1 v1.5
* RFC 2437: PKCS#1 v2.0
* RFC 3447: PKCS#1 v2.1
* RFC 8017: PKCS#1 v2.2
*
* The format of PKCS#1 v1.5 padding is:
*
@ -105,11 +102,11 @@ public final class RSAPadding {
// maximum size of the data
private final int maxDataSize;
// OAEP: main messagedigest
// OAEP: main message digest
private MessageDigest md;
// OAEP: message digest for MGF1
private MessageDigest mgfMd;
// OAEP: MGF1
private MGF1 mgf;
// OAEP: value of digest of data (user-supplied or zero-length) using md
private byte[] lHash;
@ -164,7 +161,7 @@ public final class RSAPadding {
break;
case PAD_OAEP_MGF1:
String mdName = "SHA-1";
String mgfMdName = "SHA-1";
String mgfMdName = mdName;
byte[] digestInput = null;
try {
if (spec != null) {
@ -185,10 +182,9 @@ public final class RSAPadding {
digestInput = ((PSource.PSpecified) pSrc).getValue();
}
md = MessageDigest.getInstance(mdName);
mgfMd = MessageDigest.getInstance(mgfMdName);
mgf = new MGF1(mgfMdName);
} catch (NoSuchAlgorithmException e) {
throw new InvalidKeyException
("Digest " + mdName + " not available", e);
throw new InvalidKeyException("Digest not available", e);
}
lHash = getInitialHash(md, digestInput);
int digestLen = lHash.length;
@ -196,7 +192,7 @@ public final class RSAPadding {
if (maxDataSize <= 0) {
throw new InvalidKeyException
("Key is too short for encryption using OAEPPadding" +
" with " + mdName + " and MGF1" + mgfMdName);
" with " + mdName + " and " + mgf.getName());
}
break;
default:
@ -431,10 +427,10 @@ public final class RSAPadding {
System.arraycopy(M, 0, EM, mStart, M.length);
// produce maskedDB
mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen);
mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
// produce maskSeed
mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen);
mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
return EM;
}
@ -457,8 +453,8 @@ public final class RSAPadding {
int dbStart = hLen + 1;
int dbLen = EM.length - dbStart;
mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen);
mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen);
mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
// verify lHash == lHash'
for (int i = 0; i < hLen; i++) {
@ -506,37 +502,4 @@ public final class RSAPadding {
return m;
}
}
/**
* Compute MGF1 using mgfMD as the message digest.
* Note that we combine MGF1 with the XOR operation to reduce data
* copying.
*
* We generate maskLen bytes of MGF1 from the seed and XOR it into
* out[] starting at outOfs;
*/
private void mgf1(byte[] seed, int seedOfs, int seedLen,
byte[] out, int outOfs, int maskLen) throws BadPaddingException {
byte[] C = new byte[4]; // 32 bit counter
byte[] digest = new byte[mgfMd.getDigestLength()];
while (maskLen > 0) {
mgfMd.update(seed, seedOfs, seedLen);
mgfMd.update(C);
try {
mgfMd.digest(digest, 0, digest.length);
} catch (DigestException e) {
// should never happen
throw new BadPaddingException(e.toString());
}
for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
out[outOfs++] ^= digest[i++];
}
if (maskLen > 0) {
// increment counter
for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
// empty
}
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -29,16 +29,20 @@ import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key;
import static sun.security.rsa.RSAUtil.KeyType;
/**
* Key implementation for RSA private keys, CRT form. For non-CRT private
* keys, see RSAPrivateKeyImpl. We need separate classes to ensure
* correct behavior in instanceof checks, etc.
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.
* For non-CRT private keys, see RSAPrivateKeyImpl. We need separate classes
* to ensure correct behavior in instanceof checks, etc.
*
* Note: RSA keys must be at least 512 bits long
*
@ -62,9 +66,10 @@ public final class RSAPrivateCrtKeyImpl
private BigInteger qe; // prime exponent q
private BigInteger coeff; // CRT coeffcient
// algorithmId used to identify RSA keys
static final AlgorithmId rsaId =
new AlgorithmId(AlgorithmId.RSAEncryption_oid);
// Optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId.
// Must be null for "RSA" keys.
private AlgorithmParameterSpec keyParams;
/**
* Generate a new key from its encoding. Returns a CRT key if possible
@ -73,9 +78,16 @@ public final class RSAPrivateCrtKeyImpl
public static RSAPrivateKey newKey(byte[] encoded)
throws InvalidKeyException {
RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);
if (key.getPublicExponent().signum() == 0) {
// public exponent is missing, return a non-CRT key
// check all CRT-specific components are available, if any one
// missing, return a non-CRT key instead
if ((key.getPublicExponent().signum() == 0) ||
(key.getPrimeExponentP().signum() == 0) ||
(key.getPrimeExponentQ().signum() == 0) ||
(key.getPrimeP().signum() == 0) ||
(key.getPrimeQ().signum() == 0) ||
(key.getCrtCoefficient().signum() == 0)) {
return new RSAPrivateKeyImpl(
key.algid,
key.getModulus(),
key.getPrivateExponent()
);
@ -84,21 +96,53 @@ public final class RSAPrivateCrtKeyImpl
}
}
/**
* Generate a new key from the specified type and components.
* Returns a CRT key if possible and a non-CRT key otherwise.
* Used by SunPKCS11 provider.
*/
public static RSAPrivateKey newKey(KeyType type,
AlgorithmParameterSpec params,
BigInteger n, BigInteger e, BigInteger d,
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException {
RSAPrivateKey key;
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
if ((e.signum() == 0) || (p.signum() == 0) ||
(q.signum() == 0) || (pe.signum() == 0) ||
(qe.signum() == 0) || (coeff.signum() == 0)) {
// if any component is missing, return a non-CRT key
return new RSAPrivateKeyImpl(rsaId, n, d);
} else {
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
p, q, pe, qe, coeff);
}
}
/**
* Construct a key from its encoding. Called from newKey above.
*/
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
decode(encoded);
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
try {
// this will check the validity of params
this.keyParams = RSAUtil.getParamSpec(algid);
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
}
/**
* Construct a key from its components. Used by the
* Construct a RSA key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
*/
RSAPrivateCrtKeyImpl(BigInteger n, BigInteger e, BigInteger d,
RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
BigInteger n, BigInteger e, BigInteger d,
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
this.n = n;
this.e = e;
this.d = d;
@ -107,7 +151,7 @@ public final class RSAPrivateCrtKeyImpl
this.pe = pe;
this.qe = qe;
this.coeff = coeff;
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = rsaId;
@ -132,50 +176,73 @@ public final class RSAPrivateCrtKeyImpl
}
// see JCA doc
@Override
public String getAlgorithm() {
return "RSA";
return algid.getName();
}
// see JCA doc
@Override
public BigInteger getModulus() {
return n;
}
// see JCA doc
@Override
public BigInteger getPublicExponent() {
return e;
}
// see JCA doc
@Override
public BigInteger getPrivateExponent() {
return d;
}
// see JCA doc
@Override
public BigInteger getPrimeP() {
return p;
}
// see JCA doc
@Override
public BigInteger getPrimeQ() {
return q;
}
// see JCA doc
@Override
public BigInteger getPrimeExponentP() {
return pe;
}
// see JCA doc
@Override
public BigInteger getPrimeExponentQ() {
return qe;
}
// see JCA doc
@Override
public BigInteger getCrtCoefficient() {
return coeff;
}
// see JCA doc
@Override
public AlgorithmParameterSpec getParams() {
return keyParams;
}
// return a string representation of this key for debugging
@Override
public String toString() {
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}
/**
* Parse the key. Called by PKCS8Key.
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -29,15 +29,18 @@ import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key;
/**
* Key implementation for RSA private keys, non-CRT form (modulus, private
* exponent only). For CRT private keys, see RSAPrivateCrtKeyImpl. We need
* separate classes to ensure correct behavior in instanceof checks, etc.
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
* form (modulus, private exponent only). For CRT private keys, see
* RSAPrivateCrtKeyImpl. We need separate classes to ensure correct behavior
* in instanceof checks, etc.
*
* Note: RSA keys must be at least 512 bits long
*
@ -54,16 +57,25 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
private final BigInteger n; // modulus
private final BigInteger d; // private exponent
// optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId.
// must be null for "RSA" keys.
private final AlgorithmParameterSpec keyParams;
/**
* Construct a key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
*/
RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
this.n = n;
this.d = d;
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = RSAPrivateCrtKeyImpl.rsaId;
algid = rsaId;
try {
DerOutputStream out = new DerOutputStream();
out.putInteger(0); // version must be 0
@ -85,17 +97,34 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
}
// see JCA doc
@Override
public String getAlgorithm() {
return "RSA";
return algid.getName();
}
// see JCA doc
@Override
public BigInteger getModulus() {
return n;
}
// see JCA doc
@Override
public BigInteger getPrivateExponent() {
return d;
}
// see JCA doc
@Override
public AlgorithmParameterSpec getParams() {
return keyParams;
}
// return a string representation of this key for debugging
@Override
public String toString() {
return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -29,17 +29,22 @@ import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.X509Key;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/**
* Key implementation for RSA public keys.
* RSA public key implementation for "RSA", "RSASSA-PSS" algorithms.
*
* Note: RSA keys must be at least 512 bits long
*
* @see RSAPrivateCrtKeyImpl
* @see RSAPrivateKeyImpl
* @see RSAKeyFactory
*
* @since 1.5
@ -53,18 +58,46 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
private BigInteger n; // modulus
private BigInteger e; // public exponent
// optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId
// must be null for "RSA" keys.
private AlgorithmParameterSpec keyParams;
/**
* Construct a key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
* Generate a new RSAPublicKey from the specified encoding.
* Used by SunPKCS11 provider.
*/
public RSAPublicKeyImpl(BigInteger n, BigInteger e)
public static RSAPublicKey newKey(byte[] encoded)
throws InvalidKeyException {
return new RSAPublicKeyImpl(encoded);
}
/**
* Generate a new RSAPublicKey from the specified type and components.
* Used by SunPKCS11 provider.
*/
public static RSAPublicKey newKey(KeyType type,
AlgorithmParameterSpec params, BigInteger n, BigInteger e)
throws InvalidKeyException {
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
return new RSAPublicKeyImpl(rsaId, n, e);
}
/**
* Construct a RSA key from AlgorithmId and its components. Used by
* RSAKeyFactory and RSAKeyPairGenerator.
*/
RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e)
throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
checkExponentRange(n, e);
this.n = n;
this.e = e;
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
checkExponentRange();
this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = RSAPrivateCrtKeyImpl.rsaId;
algid = rsaId;
try {
DerOutputStream out = new DerOutputStream();
out.putInteger(n);
@ -82,39 +115,57 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
/**
* Construct a key from its encoding. Used by RSAKeyFactory.
*/
public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
decode(encoded);
RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
decode(encoded); // this sets n and e value
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
checkExponentRange();
checkExponentRange(n, e);
try {
// this will check the validity of params
this.keyParams = RSAUtil.getParamSpec(algid);
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
}
private void checkExponentRange() throws InvalidKeyException {
// pkg private utility method for checking RSA modulus and public exponent
static void checkExponentRange(BigInteger mod, BigInteger exp)
throws InvalidKeyException {
// the exponent should be smaller than the modulus
if (e.compareTo(n) >= 0) {
if (exp.compareTo(mod) >= 0) {
throw new InvalidKeyException("exponent is larger than modulus");
}
// the exponent should be at least 3
if (e.compareTo(THREE) < 0) {
if (exp.compareTo(THREE) < 0) {
throw new InvalidKeyException("exponent is smaller than 3");
}
}
// see JCA doc
@Override
public String getAlgorithm() {
return "RSA";
return algid.getName();
}
// see JCA doc
@Override
public BigInteger getModulus() {
return n;
}
// see JCA doc
@Override
public BigInteger getPublicExponent() {
return e;
}
// see JCA doc
@Override
public AlgorithmParameterSpec getParams() {
return keyParams;
}
/**
* Parse the key. Called by X509Key.
*/
@ -137,9 +188,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
}
// return a string representation of this key for debugging
@Override
public String toString() {
return "Sun RSA public key, " + n.bitLength() + " bits\n modulus: "
+ n + "\n public exponent: " + e;
return "Sun " + getAlgorithm() + " public key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n public exponent: " + e;
}
protected Object writeReplace() throws java.io.ObjectStreamException {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -30,16 +30,18 @@ import java.nio.ByteBuffer;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.AlgorithmParameterSpec;
import sun.security.rsa.RSAUtil.KeyType;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
/**
* PKCS#1 RSA signatures with the various message digest algorithms.
* PKCS#1 v1.5 RSA signatures with the various message digest algorithms.
* This file contains an abstract base class with all the logic plus
* a nested static class for each of the message digest algorithms
* (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,
* SHA-384, and SHA-512.
* SHA-384, SHA-512, SHA-512/224, and SHA-512/256.
*
* @since 1.5
* @author Andreas Sterbenz
@ -85,6 +87,7 @@ public abstract class RSASignature extends SignatureSpi {
}
// initialize for verification. See JCA doc
@Override
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey);
@ -94,12 +97,14 @@ public abstract class RSASignature extends SignatureSpi {
}
// initialize for signing. See JCA doc
@Override
protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException {
engineInitSign(privateKey, null);
}
// initialize for signing. See JCA doc
@Override
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
RSAPrivateKey rsaKey =
@ -114,6 +119,11 @@ public abstract class RSASignature extends SignatureSpi {
*/
private void initCommon(RSAKey rsaKey, SecureRandom random)
throws InvalidKeyException {
try {
RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams());
} catch (ProviderException e) {
throw new InvalidKeyException("Invalid key for RSA signatures", e);
}
resetDigest();
int keySize = RSACore.getByteLength(rsaKey);
try {
@ -148,12 +158,14 @@ public abstract class RSASignature extends SignatureSpi {
}
// update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(byte b) throws SignatureException {
md.update(b);
digestReset = false;
}
// update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(byte[] b, int off, int len)
throws SignatureException {
md.update(b, off, len);
@ -161,13 +173,18 @@ public abstract class RSASignature extends SignatureSpi {
}
// update the signature with the plaintext data. See JCA doc
@Override
protected void engineUpdate(ByteBuffer b) {
md.update(b);
digestReset = false;
}
// sign the data and return the signature. See JCA doc
@Override
protected byte[] engineSign() throws SignatureException {
if (privateKey == null) {
throw new SignatureException("Missing private key");
}
byte[] digest = getDigestValue();
try {
byte[] encoded = encodeSignature(digestOID, digest);
@ -183,7 +200,11 @@ public abstract class RSASignature extends SignatureSpi {
// verify the data and return the result. See JCA doc
// should be reset to the state after engineInitVerify call.
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
if (publicKey == null) {
throw new SignatureException("Missing public key");
}
try {
if (sigBytes.length != RSACore.getByteLength(publicKey)) {
throw new SignatureException("Signature length not correct: got " +
@ -248,18 +269,35 @@ public abstract class RSASignature extends SignatureSpi {
// set parameter, not supported. See JCA doc
@Deprecated
@Override
protected void engineSetParameter(String param, Object value)
throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported");
}
// See JCA doc
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameters accepted");
}
}
// get parameter, not supported. See JCA doc
@Deprecated
@Override
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
}
// See JCA doc
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
// Nested class for MD2withRSA signatures
public static final class MD2withRSA extends RSASignature {
public MD2withRSA() {
@ -309,4 +347,17 @@ public abstract class RSASignature extends SignatureSpi {
}
}
// Nested class for SHA512/224withRSA signatures
public static final class SHA512_224withRSA extends RSASignature {
public SHA512_224withRSA() {
super("SHA-512/224", AlgorithmId.SHA512_224_oid, 11);
}
}
// Nested class for SHA512/256withRSA signatures
public static final class SHA512_256withRSA extends RSASignature {
public SHA512_256withRSA() {
super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11);
}
}
}

View file

@ -0,0 +1,155 @@
/*
* 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. 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.rsa;
import java.io.IOException;
import java.security.*;
import java.security.spec.*;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
/**
* Utility class for SunRsaSign provider.
* Currently used by RSAKeyPairGenerator and RSAKeyFactory.
*
* @since 11
*/
public class RSAUtil {
public enum KeyType {
RSA ("RSA"),
PSS ("RSASSA-PSS")
;
private final String algo;
KeyType(String keyAlgo) {
this.algo = keyAlgo;
}
public String keyAlgo() {
return algo;
}
public static KeyType lookup(String name) {
for (KeyType kt : KeyType.values()) {
if (kt.keyAlgo().equalsIgnoreCase(name)) {
return kt;
}
}
// no match
throw new ProviderException("Unsupported algorithm " + name);
}
}
public static void checkParamsAgainstType(KeyType type,
AlgorithmParameterSpec paramSpec) throws ProviderException {
switch (type) {
case RSA:
if (paramSpec != null) {
throw new ProviderException("null params expected for " +
type.keyAlgo());
}
break;
case PSS:
if ((paramSpec != null) &&
!(paramSpec instanceof PSSParameterSpec)) {
throw new ProviderException
("PSSParmeterSpec expected for " + type.keyAlgo());
}
break;
default:
throw new ProviderException
("Unsupported RSA algorithm " + type);
}
}
public static AlgorithmId createAlgorithmId(KeyType type,
AlgorithmParameterSpec paramSpec) throws ProviderException {
checkParamsAgainstType(type, paramSpec);
ObjectIdentifier oid = null;
AlgorithmParameters params = null;
try {
switch (type) {
case RSA:
oid = AlgorithmId.RSAEncryption_oid;
break;
case PSS:
if (paramSpec != null) {
params = AlgorithmParameters.getInstance(type.keyAlgo());
params.init(paramSpec);
}
oid = AlgorithmId.RSASSA_PSS_oid;
break;
default:
throw new ProviderException
("Unsupported RSA algorithm " + type);
}
AlgorithmId result;
if (params == null) {
result = new AlgorithmId(oid);
} else {
result = new AlgorithmId(oid, params);
}
return result;
} catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
// should not happen
throw new ProviderException(e);
}
}
public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid)
throws ProviderException {
if (algid == null) {
throw new ProviderException("AlgorithmId should not be null");
}
return getParamSpec(algid.getParameters());
}
public static AlgorithmParameterSpec getParamSpec(AlgorithmParameters params)
throws ProviderException {
if (params == null) return null;
String algName = params.getAlgorithm();
KeyType type = KeyType.lookup(algName);
Class<? extends AlgorithmParameterSpec> specCls;
switch (type) {
case RSA:
throw new ProviderException("No params accepted for " +
type.keyAlgo());
case PSS:
specCls = PSSParameterSpec.class;
break;
default:
throw new ProviderException("Unsupported RSA algorithm: " + algName);
}
try {
return params.getParameterSpec(specCls);
} catch (Exception e) {
throw new ProviderException(e);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -41,11 +41,10 @@ public final class SunRsaSignEntries {
public static void putEntries(Map<Object, Object> map) {
// main algorithms
map.put("KeyFactory.RSA",
"sun.security.rsa.RSAKeyFactory");
"sun.security.rsa.RSAKeyFactory$Legacy");
map.put("KeyPairGenerator.RSA",
"sun.security.rsa.RSAKeyPairGenerator");
"sun.security.rsa.RSAKeyPairGenerator$Legacy");
map.put("Signature.MD2withRSA",
"sun.security.rsa.RSASignature$MD2withRSA");
map.put("Signature.MD5withRSA",
@ -60,9 +59,21 @@ public final class SunRsaSignEntries {
"sun.security.rsa.RSASignature$SHA384withRSA");
map.put("Signature.SHA512withRSA",
"sun.security.rsa.RSASignature$SHA512withRSA");
map.put("Signature.SHA512/224withRSA",
"sun.security.rsa.RSASignature$SHA512_224withRSA");
map.put("Signature.SHA512/256withRSA",
"sun.security.rsa.RSASignature$SHA512_256withRSA");
map.put("KeyFactory.RSASSA-PSS",
"sun.security.rsa.RSAKeyFactory$PSS");
map.put("KeyPairGenerator.RSASSA-PSS",
"sun.security.rsa.RSAKeyPairGenerator$PSS");
map.put("Signature.RSASSA-PSS",
"sun.security.rsa.RSAPSSSignature");
map.put("AlgorithmParameters.RSASSA-PSS",
"sun.security.rsa.PSSParameters");
// attributes for supported key classes
String rsaKeyClasses = "java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey";
map.put("Signature.MD2withRSA SupportedKeyClasses", rsaKeyClasses);
@ -72,9 +83,11 @@ public final class SunRsaSignEntries {
map.put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512/224withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512/256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.RSASSA-PSS SupportedKeyClasses", rsaKeyClasses);
// aliases
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
@ -102,6 +115,21 @@ public final class SunRsaSignEntries {
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.15", "SHA512/224withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.15", "SHA512/224withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.16", "SHA512/256withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.16", "SHA512/256withRSA");
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -27,6 +27,7 @@
package sun.security.ssl;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
/**
* Signature implementation for the SSL/TLS RSA Signature variant with both
@ -200,6 +201,14 @@ public final class RSASignature extends SignatureSpi {
sha = digests[1];
}
@Override
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException("No parameters accepted");
}
}
@Override
@SuppressWarnings("deprecation")
protected Object engineGetParameter(String param)
@ -207,4 +216,8 @@ public final class RSASignature extends SignatureSpi {
throw new InvalidParameterException("Parameters not supported");
}
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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
@ -161,12 +161,12 @@ public abstract class SunJSSE extends java.security.Provider {
private void doRegister(boolean isfips) {
if (isfips == false) {
put("KeyFactory.RSA",
"sun.security.rsa.RSAKeyFactory");
"sun.security.rsa.RSAKeyFactory$Legacy");
put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
put("KeyPairGenerator.RSA",
"sun.security.rsa.RSAKeyPairGenerator");
"sun.security.rsa.RSAKeyPairGenerator$Legacy");
put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@ -56,6 +56,7 @@ public final class SecurityProviderConstants {
public static final int DEF_DSA_KEY_SIZE;
public static final int DEF_RSA_KEY_SIZE;
public static final int DEF_RSASSA_PSS_KEY_SIZE;
public static final int DEF_DH_KEY_SIZE;
public static final int DEF_EC_KEY_SIZE;
@ -66,6 +67,7 @@ public final class SecurityProviderConstants {
(KEY_LENGTH_PROP);
int dsaKeySize = 2048;
int rsaKeySize = 2048;
int rsaSsaPssKeySize = rsaKeySize; // default to same value as RSA
int dhKeySize = 2048;
int ecKeySize = 256;
@ -98,6 +100,8 @@ public final class SecurityProviderConstants {
dsaKeySize = value;
} else if (algoName.equals("RSA")) {
rsaKeySize = value;
} else if (algoName.equals("RSASSA-PSS")) {
rsaSsaPssKeySize = value;
} else if (algoName.equals("DH")) {
dhKeySize = value;
} else if (algoName.equals("EC")) {
@ -125,6 +129,7 @@ public final class SecurityProviderConstants {
}
DEF_DSA_KEY_SIZE = dsaKeySize;
DEF_RSA_KEY_SIZE = rsaKeySize;
DEF_RSASSA_PSS_KEY_SIZE = rsaSsaPssKeySize;
DEF_DH_KEY_SIZE = dhKeySize;
DEF_EC_KEY_SIZE = ecKeySize;
}

View file

@ -0,0 +1,115 @@
/*
* 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. 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.util;
import java.io.IOException;
import java.security.*;
import java.security.spec.*;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.rsa.RSAUtil;
/**
* Utility class for Signature related operations. Currently used by various
* internal PKI classes such as sun.security.x509.X509CertImpl,
* sun.security.pkcs.SignerInfo, for setting signature parameters.
*
* @since 11
*/
public class SignatureUtil {
// Utility method of creating an AlgorithmParameters object with
// the specified algorithm name and encoding
private static AlgorithmParameters createAlgorithmParameters(String algName,
byte[] paramBytes) throws ProviderException {
try {
AlgorithmParameters result =
AlgorithmParameters.getInstance(algName);
result.init(paramBytes);
return result;
} catch (NoSuchAlgorithmException | IOException e) {
throw new ProviderException(e);
}
}
private static AlgorithmParameterSpec getParamSpec(String sigName,
AlgorithmParameters params)
throws InvalidAlgorithmParameterException, ProviderException {
if (params == null) return null;
if (sigName.toUpperCase().indexOf("RSA") == -1) {
throw new ProviderException
("Unrecognized algorithm for signature parameters " +
sigName);
}
// AlgorithmParameters.getAlgorithm() may returns oid if it's
// created during DER decoding. Convert to use the standard name
// before passing it to RSAUtil
String alg = params.getAlgorithm();
if (alg.equalsIgnoreCase(sigName) || alg.indexOf(".") != -1) {
try {
params = createAlgorithmParameters(sigName,
params.getEncoded());
} catch (IOException e) {
throw new ProviderException(e);
}
}
return RSAUtil.getParamSpec(params);
}
// Special method for setting the specified parameter bytes into the
// specified Signature object as signature parameters.
public static void specialSetParameter(Signature sig, byte[] paramBytes)
throws InvalidAlgorithmParameterException, ProviderException {
AlgorithmParameters params = null;
if (paramBytes != null) {
String sigName = sig.getAlgorithm();
params = createAlgorithmParameters(sigName, paramBytes);
}
specialSetParameter(sig, params);
}
// Special method for setting the specified AlgorithmParameter object
// into the specified Signature object as signature parameters.
public static void specialSetParameter(Signature sig,
AlgorithmParameters params)
throws InvalidAlgorithmParameterException, ProviderException {
String sigName = sig.getAlgorithm();
if (params != null) {
sig.setParameter(getParamSpec(sigName, params));
} else {
try {
sig.setParameter(null);
} catch (UnsupportedOperationException e) {
// ignore for maintaining backward compatibility
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -182,6 +182,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
algid.equals((Object)SHA256_oid) ||
algid.equals((Object)SHA384_oid) ||
algid.equals((Object)SHA512_oid) ||
algid.equals((Object)SHA512_224_oid) ||
algid.equals((Object)SHA512_256_oid) ||
algid.equals((Object)DSA_oid) ||
algid.equals((Object)sha1WithDSA_oid)) {
; // no parameter part encoded
@ -483,11 +485,24 @@ public class AlgorithmId implements Serializable, DerEncoder {
name.equalsIgnoreCase("SHA224")) {
return AlgorithmId.SHA224_oid;
}
if (name.equalsIgnoreCase("SHA-512/224") ||
name.equalsIgnoreCase("SHA512/224")) {
return AlgorithmId.SHA512_224_oid;
}
if (name.equalsIgnoreCase("SHA-512/256") ||
name.equalsIgnoreCase("SHA512/256")) {
return AlgorithmId.SHA512_256_oid;
}
// Various public key algorithms
if (name.equalsIgnoreCase("RSA")) {
return AlgorithmId.RSAEncryption_oid;
}
if (name.equalsIgnoreCase("RSASSA-PSS")) {
return AlgorithmId.RSASSA_PSS_oid;
}
if (name.equalsIgnoreCase("RSAES-OAEP")) {
return AlgorithmId.RSAES_OAEP_oid;
}
if (name.equalsIgnoreCase("Diffie-Hellman")
|| name.equalsIgnoreCase("DH")) {
return AlgorithmId.DH_oid;
@ -648,6 +663,12 @@ public class AlgorithmId implements Serializable, DerEncoder {
public static final ObjectIdentifier SHA512_oid =
ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3});
public static final ObjectIdentifier SHA512_224_oid =
ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 5});
public static final ObjectIdentifier SHA512_256_oid =
ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 6});
/*
* COMMON PUBLIC KEY TYPES
*/
@ -656,8 +677,6 @@ public class AlgorithmId implements Serializable, DerEncoder {
private static final int[] DSA_OIW_data = { 1, 3, 14, 3, 2, 12 };
private static final int[] DSA_PKIX_data = { 1, 2, 840, 10040, 4, 1 };
private static final int[] RSA_data = { 2, 5, 8, 1, 1 };
private static final int[] RSAEncryption_data =
{ 1, 2, 840, 113549, 1, 1, 1 };
public static final ObjectIdentifier DH_oid;
public static final ObjectIdentifier DH_PKIX_oid;
@ -666,7 +685,12 @@ public class AlgorithmId implements Serializable, DerEncoder {
public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
public static final ObjectIdentifier RSA_oid;
public static final ObjectIdentifier RSAEncryption_oid;
public static final ObjectIdentifier RSAEncryption_oid =
oid(1, 2, 840, 113549, 1, 1, 1);
public static final ObjectIdentifier RSAES_OAEP_oid =
oid(1, 2, 840, 113549, 1, 1, 7);
public static final ObjectIdentifier RSASSA_PSS_oid =
oid(1, 2, 840, 113549, 1, 1, 10);
/*
* COMMON SECRET KEY TYPES
@ -693,6 +717,7 @@ public class AlgorithmId implements Serializable, DerEncoder {
{ 1, 2, 840, 113549, 1, 1, 12 };
private static final int[] sha512WithRSAEncryption_data =
{ 1, 2, 840, 113549, 1, 1, 13 };
private static final int[] shaWithDSA_OIW_data =
{ 1, 3, 14, 3, 2, 13 };
private static final int[] sha1WithDSA_OIW_data =
@ -708,6 +733,11 @@ public class AlgorithmId implements Serializable, DerEncoder {
public static final ObjectIdentifier sha256WithRSAEncryption_oid;
public static final ObjectIdentifier sha384WithRSAEncryption_oid;
public static final ObjectIdentifier sha512WithRSAEncryption_oid;
public static final ObjectIdentifier sha512_224WithRSAEncryption_oid =
oid(1, 2, 840, 113549, 1, 1, 15);
public static final ObjectIdentifier sha512_256WithRSAEncryption_oid =
oid(1, 2, 840, 113549, 1, 1, 16);;
public static final ObjectIdentifier shaWithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_oid;
@ -796,13 +826,6 @@ public class AlgorithmId implements Serializable, DerEncoder {
*/
RSA_oid = ObjectIdentifier.newInternal(RSA_data);
/**
* Algorithm ID for RSA keys used with RSA encryption, as defined
* in PKCS #1. There are no parameters associated with this algorithm.
* OID = 1.2.840.113549.1.1.1
*/
RSAEncryption_oid = ObjectIdentifier.newInternal(RSAEncryption_data);
/**
* Identifies a signing algorithm where an MD2 digest is encrypted
* using an RSA private key; defined in PKCS #1. Use of this
@ -898,6 +921,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
nameTable.put(SHA256_oid, "SHA-256");
nameTable.put(SHA384_oid, "SHA-384");
nameTable.put(SHA512_oid, "SHA-512");
nameTable.put(SHA512_224_oid, "SHA-512/224");
nameTable.put(SHA512_256_oid, "SHA-512/256");
nameTable.put(RSAEncryption_oid, "RSA");
nameTable.put(RSA_oid, "RSA");
nameTable.put(DH_oid, "Diffie-Hellman");
@ -927,6 +952,11 @@ public class AlgorithmId implements Serializable, DerEncoder {
nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA");
nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA");
nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA");
nameTable.put(sha512_224WithRSAEncryption_oid, "SHA512/224withRSA");
nameTable.put(sha512_256WithRSAEncryption_oid, "SHA512/256withRSA");
nameTable.put(RSASSA_PSS_oid, "RSASSA-PSS");
nameTable.put(RSAES_OAEP_oid, "RSAES-OAEP");
nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES");
nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2");
nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -29,27 +29,18 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.Principal;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Signature;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.cert.X509CRLEntry;
import java.security.cert.CRLException;
import java.security.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import sun.security.provider.X509Factory;
import sun.security.util.*;
import sun.security.util.HexDumpEncoder;
/**
* <p>
@ -384,8 +375,19 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
} else {
sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
}
sigVerf.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selection happens when key is set
try {
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
} catch (ProviderException e) {
throw new CRLException(e.getMessage(), e.getCause());
} catch (InvalidAlgorithmParameterException e) {
throw new CRLException(e);
}
if (tbsCertList == null) {
throw new CRLException("Uninitialized CRL");
}
@ -428,8 +430,19 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
} else {
sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
}
sigVerf.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selection happens when key is set
try {
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
} catch (ProviderException e) {
throw new CRLException(e.getMessage(), e.getCause());
} catch (InvalidAlgorithmParameterException e) {
throw new CRLException(e);
}
if (tbsCertList == null) {
throw new CRLException("Uninitialized CRL");
}

View file

@ -34,6 +34,7 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.*;
@ -41,7 +42,6 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.x500.X500Principal;
import sun.security.util.HexDumpEncoder;
import java.util.Base64;
import sun.security.util.*;
import sun.security.provider.X509Factory;
@ -388,7 +388,6 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
public void verify(PublicKey key)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException {
verify(key, "");
}
@ -435,8 +434,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
} else {
sigVerf = Signature.getInstance(algId.getName(), sigProvider);
}
sigVerf.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selection happens when key is set
try {
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
} catch (ProviderException e) {
throw new CertificateException(e.getMessage(), e.getCause());
} catch (InvalidAlgorithmParameterException e) {
throw new CertificateException(e);
}
byte[] rawCert = info.getEncodedInfo();
sigVerf.update(rawCert, 0, rawCert.length);
@ -480,8 +490,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
} else {
sigVerf = Signature.getInstance(algId.getName(), sigProvider);
}
sigVerf.initVerify(key);
// set parameters after Signature.initSign/initVerify call,
// so the deferred provider selection happens when key is set
try {
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
} catch (ProviderException e) {
throw new CertificateException(e.getMessage(), e.getCause());
} catch (InvalidAlgorithmParameterException e) {
throw new CertificateException(e);
}
byte[] rawCert = info.getEncodedInfo();
sigVerf.update(rawCert, 0, rawCert.length);
@ -536,6 +557,42 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
public void sign(PrivateKey key, String algorithm, String provider)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException {
try {
sign(key, null, algorithm, provider);
} catch (InvalidAlgorithmParameterException e) {
// should not happen; re-throw just in case
throw new SignatureException(e);
}
}
/**
* Creates an X.509 certificate, and signs it using the given key
* (associating a signature algorithm and an X.500 name), signature
* parameters, and security provider. If the given provider name
* is null or empty, the implementation look up will be based on
* provider configurations.
* This operation is used to implement the certificate generation
* functionality of a certificate authority.
*
* @param key the private key used for signing
* @param signingParams the parameters used for signing
* @param algorithm the name of the signature algorithm used
* @param provider the name of the provider, may be null
*
* @exception NoSuchAlgorithmException on unsupported signature
* algorithms
* @exception InvalidKeyException on incorrect key
* @exception InvalidAlgorithmParameterException on invalid signature
* parameters
* @exception NoSuchProviderException on incorrect provider
* @exception SignatureException on signature errors
* @exception CertificateException on encoding errors
*/
public void sign(PrivateKey key, AlgorithmParameterSpec signingParams,
String algorithm, String provider)
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, InvalidAlgorithmParameterException,
NoSuchProviderException, SignatureException {
try {
if (readOnly)
throw new CertificateEncodingException(
@ -548,9 +605,22 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
sigEngine.initSign(key);
// in case the name is reset
algId = AlgorithmId.get(sigEngine.getAlgorithm());
// set parameters after Signature.initSign/initVerify call, so
// the deferred provider selection happens when the key is set
try {
sigEngine.setParameter(signingParams);
} catch (UnsupportedOperationException e) {
// for backward compatibility, only re-throw when
// parameters is not null
if (signingParams != null) throw e;
}
// in case the name is reset
if (signingParams != null) {
algId = AlgorithmId.get(sigEngine.getParameters());
} else {
algId = AlgorithmId.get(algorithm);
}
DerOutputStream out = new DerOutputStream();
DerOutputStream tmp = new DerOutputStream();