8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.AccessController;
import java.security.AlgorithmConstraints;
import java.security.PrivilegedAction;
import java.security.Security;
import java.util.Set;
/**
* The class contains common functionality for algorithm constraints classes.
*/
public abstract class AbstractAlgorithmConstraints
implements AlgorithmConstraints {
protected final AlgorithmDecomposer decomposer;
protected AbstractAlgorithmConstraints(AlgorithmDecomposer decomposer) {
this.decomposer = decomposer;
}
// Get algorithm constraints from the specified security property.
static String[] getAlgorithms(String propertyName) {
String property = AccessController.doPrivileged(
new PrivilegedAction<String>() {
@Override
public String run() {
return Security.getProperty(propertyName);
}
});
String[] algorithmsInProperty = null;
if (property != null && !property.isEmpty()) {
// remove double quote marks from beginning/end of the property
if (property.length() >= 2 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
algorithmsInProperty = property.split(",");
for (int i = 0; i < algorithmsInProperty.length; i++) {
algorithmsInProperty[i] = algorithmsInProperty[i].trim();
}
}
// map the disabled algorithms
if (algorithmsInProperty == null) {
algorithmsInProperty = new String[0];
}
return algorithmsInProperty;
}
static boolean checkAlgorithm(String[] algorithms, String algorithm,
AlgorithmDecomposer decomposer) {
if (algorithm == null || algorithm.length() == 0) {
throw new IllegalArgumentException("No algorithm name specified");
}
Set<String> elements = null;
for (String item : algorithms) {
if (item == null || item.isEmpty()) {
continue;
}
// check the full name
if (item.equalsIgnoreCase(algorithm)) {
return false;
}
// decompose the algorithm into sub-elements
if (elements == null) {
elements = decomposer.decompose(algorithm);
}
// check the items of the algorithm
for (String element : elements) {
if (item.equalsIgnoreCase(element)) {
return false;
}
}
}
return true;
}
}

View file

@ -0,0 +1,192 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.util.HashSet;
import java.util.Set;
import java.util.Arrays;
import java.util.Collection;
import java.util.regex.Pattern;
/**
* The class decomposes standard algorithms into sub-elements.
*/
public class AlgorithmDecomposer {
// '(?<!padd)in': match 'in' but not preceded with 'padd'.
private static final Pattern PATTERN =
Pattern.compile("with|and|(?<!padd)in", Pattern.CASE_INSENSITIVE);
private static Set<String> decomposeImpl(String algorithm) {
Set<String> elements = new HashSet<>();
// algorithm/mode/padding
String[] transTokens = algorithm.split("/");
for (String transToken : transTokens) {
if (transToken == null || transToken.isEmpty()) {
continue;
}
// PBEWith<digest>And<encryption>
// PBEWith<prf>And<encryption>
// OAEPWith<digest>And<mgf>Padding
// <digest>with<encryption>
// <digest>with<encryption>and<mgf>
// <digest>with<encryption>in<format>
String[] tokens = PATTERN.split(transToken);
for (String token : tokens) {
if (token == null || token.isEmpty()) {
continue;
}
elements.add(token);
}
}
return elements;
}
/**
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
// In Java standard algorithm name specification, for different
// purpose, the SHA-1 and SHA-2 algorithm names are different. For
// example, for MessageDigest, the standard name is "SHA-256", while
// for Signature, the digest algorithm component is "SHA256" for
// signature algorithm "SHA256withRSA". So we need to check both
// "SHA-256" and "SHA256" to make the right constraint checking.
// handle special name: SHA-1 and SHA1
if (elements.contains("SHA1") && !elements.contains("SHA-1")) {
elements.add("SHA-1");
}
if (elements.contains("SHA-1") && !elements.contains("SHA1")) {
elements.add("SHA1");
}
// handle special name: SHA-224 and SHA224
if (elements.contains("SHA224") && !elements.contains("SHA-224")) {
elements.add("SHA-224");
}
if (elements.contains("SHA-224") && !elements.contains("SHA224")) {
elements.add("SHA224");
}
// handle special name: SHA-256 and SHA256
if (elements.contains("SHA256") && !elements.contains("SHA-256")) {
elements.add("SHA-256");
}
if (elements.contains("SHA-256") && !elements.contains("SHA256")) {
elements.add("SHA256");
}
// handle special name: SHA-384 and SHA384
if (elements.contains("SHA384") && !elements.contains("SHA-384")) {
elements.add("SHA-384");
}
if (elements.contains("SHA-384") && !elements.contains("SHA384")) {
elements.add("SHA384");
}
// handle special name: SHA-512 and SHA512
if (elements.contains("SHA512") && !elements.contains("SHA-512")) {
elements.add("SHA-512");
}
if (elements.contains("SHA-512") && !elements.contains("SHA512")) {
elements.add("SHA512");
}
return elements;
}
/**
* Get aliases of the specified algorithm.
*
* May support more algorithms in the future.
*/
public static Collection<String> getAliases(String algorithm) {
String[] aliases;
if (algorithm.equalsIgnoreCase("DH") ||
algorithm.equalsIgnoreCase("DiffieHellman")) {
aliases = new String[] {"DH", "DiffieHellman"};
} else {
aliases = new String[] {algorithm};
}
return Arrays.asList(aliases);
}
private static void hasLoop(Set<String> elements, String find, String replace) {
if (elements.contains(find)) {
if (!elements.contains(replace)) {
elements.add(replace);
}
elements.remove(find);
}
}
/*
* This decomposes a standard name into sub-elements with a consistent
* message digest algorithm name to avoid overly complicated checking.
*/
public static Set<String> decomposeOneHash(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
hasLoop(elements, "SHA-1", "SHA1");
hasLoop(elements, "SHA-224", "SHA224");
hasLoop(elements, "SHA-256", "SHA256");
hasLoop(elements, "SHA-384", "SHA384");
hasLoop(elements, "SHA-512", "SHA512");
return elements;
}
/*
* The provided message digest algorithm name will return a consistent
* naming scheme.
*/
public static String hashName(String algorithm) {
return algorithm.replace("-", "");
}
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.File;
import java.io.FileInputStream;
import java.security.AccessController;
import java.security.KeyStore;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import sun.security.x509.X509CertImpl;
/**
* The purpose of this class is to determine the trust anchor certificates is in
* the cacerts file. This is used for PKIX CertPath checking.
*/
public class AnchorCertificates {
private static final Debug debug = Debug.getInstance("certpath");
private static final String HASH = "SHA-256";
private static Set<String> certs = Collections.emptySet();
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
"lib/security/cacerts");
KeyStore cacerts;
try {
cacerts = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(f)) {
cacerts.load(fis, null);
certs = new HashSet<>();
Enumeration<String> list = cacerts.aliases();
String alias;
while (list.hasMoreElements()) {
alias = list.nextElement();
// Check if this cert is labeled a trust anchor.
if (alias.contains(" [jdk")) {
X509Certificate cert = (X509Certificate) cacerts
.getCertificate(alias);
certs.add(X509CertImpl.getFingerprint(HASH, cert));
}
}
}
} catch (Exception e) {
if (debug != null) {
debug.println("Error parsing cacerts");
}
e.printStackTrace();
}
return null;
}
});
}
/**
* Checks if a certificate is a trust anchor.
*
* @param cert the certificate to check
* @return true if the certificate is trusted.
*/
public static boolean contains(X509Certificate cert) {
String key = X509CertImpl.getFingerprint(HASH, cert);
boolean result = certs.contains(key);
if (result && debug != null) {
debug.println("AnchorCertificate.contains: matched " +
cert.getSubjectDN());
}
return result;
}
private AnchorCertificates() {}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "invalid null input: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "Invalid NTSid value"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [Primary Group]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [Supplementary Group]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "Unable to properly expand {0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (No such file or directory)"},
{"Configuration.Error.No.such.file.or.directory",
"Configuration Error:\n\tNo such file or directory"},
{"Configuration.Error.Invalid.control.flag.flag",
"Configuration Error:\n\tInvalid control flag, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Configuration Error:\n\tCan not specify multiple entries for {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Configuration Error:\n\texpected [{0}], read [end of file]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Configuration Error:\n\tLine {0}: expected [{1}], found [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"Configuration Error:\n\tLine {0}: expected [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Configuration Error:\n\tLine {0}: system property [{1}] expanded to empty value"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","username: "},
{"password.","password: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Please enter keystore information"},
{"Keystore.alias.","Keystore alias: "},
{"Keystore.password.","Keystore password: "},
{"Private.key.password.optional.",
"Private key password (optional): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos username [{0}]: "},
{"Kerberos.password.for.username.",
"Kerberos password for {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_de extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "Ung\u00FCltige Nulleingabe: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "Ung\u00FCltiger NTSid-Wert"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [Prim\u00E4rgruppe]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [Zusatzgruppe]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "{0} kann nicht ordnungsgem\u00E4\u00DF erweitert werden"},
{"extra.config.No.such.file.or.directory.",
"{0} (Datei oder Verzeichnis nicht vorhanden)"},
{"Configuration.Error.No.such.file.or.directory",
"Konfigurationsfehler:\n\tDatei oder Verzeichnis nicht vorhanden"},
{"Configuration.Error.Invalid.control.flag.flag",
"Konfigurationsfehler:\n\tUng\u00FCltiges Steuerkennzeichen {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Konfigurationsfehler:\n\tEs k\u00F6nnen nicht mehrere Angaben f\u00FCr {0} gemacht werden."},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Konfigurationsfehler:\n\t[{0}] erwartet, [Dateiende] gelesen"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Konfigurationsfehler:\n\tZeile {0}: [{1}] erwartet, [{2}] gefunden"},
{"Configuration.Error.Line.line.expected.expect.",
"Konfigurationsfehler:\n\tZeile {0}: [{1}] erwartet"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Konfigurationsfehler:\n\tZeile {0}: Systemeigenschaft [{1}] auf leeren Wert erweitert"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","Benutzername: "},
{"password.","Kennwort: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Geben Sie die Keystore-Informationen ein"},
{"Keystore.alias.","Keystore-Alias: "},
{"Keystore.password.","Keystore-Kennwort: "},
{"Private.key.password.optional.",
"Private Key-Kennwort (optional): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos-Benutzername [{0}]: "},
{"Kerberos.password.for.username.",
"Kerberos-Kennwort f\u00FCr {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_es extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "entrada nula no v\u00E1lida: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "Valor de NTSid no v\u00E1lido"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [Grupo Principal] {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [Grupo Adicional] {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "No se ha podido ampliar correctamente {0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (No existe tal archivo o directorio)"},
{"Configuration.Error.No.such.file.or.directory",
"Error de Configuraci\u00F3n:\n\tNo existe tal archivo o directorio"},
{"Configuration.Error.Invalid.control.flag.flag",
"Error de Configuraci\u00F3n:\n\tIndicador de control no v\u00E1lido, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Error de Configuraci\u00F3n:\n\tNo se pueden especificar varias entradas para {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Error de configuraci\u00F3n:\n\tse esperaba [{0}], se ha le\u00EDdo [final de archivo]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Error de configuraci\u00F3n:\n\tL\u00EDnea {0}: se esperaba [{1}], se ha encontrado [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"Error de configuraci\u00F3n:\n\tL\u00EDnea {0}: se esperaba [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Error de configuraci\u00F3n:\n\tL\u00EDnea {0}: propiedad de sistema [{1}] ampliada a valor vac\u00EDo"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","nombre de usuario: "},
{"password.","contrase\u00F1a: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Introduzca la informaci\u00F3n del almac\u00E9n de claves"},
{"Keystore.alias.","Alias de Almac\u00E9n de Claves: "},
{"Keystore.password.","Contrase\u00F1a de Almac\u00E9n de Claves: "},
{"Private.key.password.optional.",
"Contrase\u00F1a de Clave Privada (opcional): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Nombre de usuario de Kerberos [{0}]: "},
{"Kerberos.password.for.username.",
"Contrase\u00F1a de Kerberos de {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_fr extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "entr\u00E9e NULL non valide : {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal : {0}"},
{"NTNumericCredential.name", "NTNumericCredential : {0}"},
{"Invalid.NTSid.value", "Valeur de NTSid non valide"},
{"NTSid.name", "NTSid : {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal : {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal : {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal : {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal : {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal : {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [groupe principal] : {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [groupe suppl\u00E9mentaire] : {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal : {0}"},
{"UnixPrincipal.name", "UnixPrincipal : {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "Impossible de d\u00E9velopper {0} correctement"},
{"extra.config.No.such.file.or.directory.",
"{0} (fichier ou r\u00E9pertoire inexistant)"},
{"Configuration.Error.No.such.file.or.directory",
"Erreur de configuration :\n\tCe fichier ou r\u00E9pertoire n'existe pas"},
{"Configuration.Error.Invalid.control.flag.flag",
"Erreur de configuration :\n\tIndicateur de contr\u00F4le non valide, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Erreur de configuration :\n\tImpossible de sp\u00E9cifier des entr\u00E9es multiples pour {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Erreur de configuration :\n\tAttendu : [{0}], lu : [fin de fichier]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Erreur de configuration :\n\tLigne {0} : attendu [{1}], trouv\u00E9 [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"Erreur de configuration :\n\tLigne {0} : attendu [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Erreur de configuration :\n\tLigne {0} : propri\u00E9t\u00E9 syst\u00E8me [{1}] d\u00E9velopp\u00E9e en valeur vide"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","nom utilisateur : "},
{"password.","mot de passe : "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Entrez les informations du fichier de cl\u00E9s"},
{"Keystore.alias.","Alias du fichier de cl\u00E9s : "},
{"Keystore.password.","Mot de passe pour fichier de cl\u00E9s : "},
{"Private.key.password.optional.",
"Mot de passe de la cl\u00E9 priv\u00E9e (facultatif) : "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Nom utilisateur Kerberos [{0}] : "},
{"Kerberos.password.for.username.",
"Mot de passe Kerberos pour {0} : "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_it extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "input nullo non valido: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "Valore NTSid non valido"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [gruppo primario]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [gruppo supplementare]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "Impossibile espandere correttamente {0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (file o directory inesistente)"},
{"Configuration.Error.No.such.file.or.directory",
"Errore di configurazione:\n\tFile o directory inesistente"},
{"Configuration.Error.Invalid.control.flag.flag",
"Errore di configurazione:\n\tflag di controllo non valido, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Errore di configurazione:\n\timpossibile specificare pi\u00F9 valori per {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Errore di configurazione:\n\tprevisto [{0}], letto [end of file]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Errore di configurazione:\n\triga {0}: previsto [{1}], trovato [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"Errore di configurazione:\n\triga {0}: previsto [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Errore di configurazione:\n\triga {0}: propriet\u00E0 di sistema [{1}] espansa a valore vuoto"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","Nome utente: "},
{"password.","Password: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Immettere le informazioni per il keystore"},
{"Keystore.alias.","Alias keystore: "},
{"Keystore.password.","Password keystore: "},
{"Private.key.password.optional.",
"Password chiave privata (opzionale): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Nome utente Kerberos [{0}]: "},
{"Kerberos.password.for.username.",
"Password Kerberos per {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_ja extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "\u7121\u52B9\u306Anull\u306E\u5165\u529B: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "\u7121\u52B9\u306ANTSid\u5024"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [\u4E3B\u30B0\u30EB\u30FC\u30D7]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [\u88DC\u52A9\u30B0\u30EB\u30FC\u30D7]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "{0}\u3092\u6B63\u3057\u304F\u5C55\u958B\u3067\u304D\u307E\u305B\u3093"},
{"extra.config.No.such.file.or.directory.",
"{0}(\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u5B58\u5728\u3057\u307E\u305B\u3093)"},
{"Configuration.Error.No.such.file.or.directory",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u5B58\u5728\u3057\u307E\u305B\u3093"},
{"Configuration.Error.Invalid.control.flag.flag",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t\u7121\u52B9\u306A\u5236\u5FA1\u30D5\u30E9\u30B0: {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t{0}\u306B\u8907\u6570\u306E\u30A8\u30F3\u30C8\u30EA\u3092\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t[{0}]\u3067\u306F\u306A\u304F\u3001[\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A]\u304C\u8AAD\u307F\u8FBC\u307E\u308C\u307E\u3057\u305F"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t\u884C{0}: [{1}]\u3067\u306F\u306A\u304F\u3001[{2}]\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F"},
{"Configuration.Error.Line.line.expected.expect.",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t\u884C{0}: [{1}]\u304C\u8981\u6C42\u3055\u308C\u307E\u3057\u305F"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"\u69CB\u6210\u30A8\u30E9\u30FC:\n\t\u884C{0}: \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3[{1}]\u304C\u7A7A\u306E\u5024\u306B\u5C55\u958B\u3055\u308C\u307E\u3057\u305F"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","\u30E6\u30FC\u30B6\u30FC\u540D: "},
{"password.","\u30D1\u30B9\u30EF\u30FC\u30C9: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"\u30AD\u30FC\u30B9\u30C8\u30A2\u60C5\u5831\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044"},
{"Keystore.alias.","\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5225\u540D: "},
{"Keystore.password.","\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9: "},
{"Private.key.password.optional.",
"\u79D8\u5BC6\u9375\u306E\u30D1\u30B9\u30EF\u30FC\u30C9(\u30AA\u30D7\u30B7\u30E7\u30F3): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos\u30E6\u30FC\u30B6\u30FC\u540D[{0}]: "},
{"Kerberos.password.for.username.",
"{0}\u306EKerberos\u30D1\u30B9\u30EF\u30FC\u30C9: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_ko extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "\uBD80\uC801\uD569\uD55C \uB110 \uC785\uB825: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "NTSid \uAC12\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4."},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [\uAE30\uBCF8 \uADF8\uB8F9]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [\uBCF4\uC870 \uADF8\uB8F9]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "{0}\uC744(\uB97C) \uC81C\uB300\uB85C \uD655\uC7A5\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"extra.config.No.such.file.or.directory.",
"{0}(\uD574\uB2F9 \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.)"},
{"Configuration.Error.No.such.file.or.directory",
"\uAD6C\uC131 \uC624\uB958:\n\t\uD574\uB2F9 \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"Configuration.Error.Invalid.control.flag.flag",
"\uAD6C\uC131 \uC624\uB958:\n\t\uC81C\uC5B4 \uD50C\uB798\uADF8\uAC00 \uBD80\uC801\uD569\uD568, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"\uAD6C\uC131 \uC624\uB958:\n\t{0}\uC5D0 \uB300\uD574 \uC5EC\uB7EC \uD56D\uBAA9\uC744 \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"Configuration.Error.expected.expect.read.end.of.file.",
"\uAD6C\uC131 \uC624\uB958:\n\t[{0}]\uC774(\uAC00) \uD544\uC694\uD558\uC9C0\uB9CC [\uD30C\uC77C\uC758 \uB05D]\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4."},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"\uAD6C\uC131 \uC624\uB958:\n\t{0} \uD589: [{1}]\uC774(\uAC00) \uD544\uC694\uD558\uC9C0\uB9CC [{2}]\uC774(\uAC00) \uBC1C\uACAC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"Configuration.Error.Line.line.expected.expect.",
"\uAD6C\uC131 \uC624\uB958:\n\t{0} \uD589: [{1}]\uC774(\uAC00) \uD544\uC694\uD569\uB2C8\uB2E4."},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"\uAD6C\uC131 \uC624\uB958:\n\t{0} \uD589: \uC2DC\uC2A4\uD15C \uC18D\uC131 [{1}]\uC774(\uAC00) \uBE48 \uAC12\uC73C\uB85C \uD655\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
// com.sun.security.auth.module.JndiLoginModule
{"username.","\uC0AC\uC6A9\uC790 \uC774\uB984: "},
{"password.","\uBE44\uBC00\uBC88\uD638: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"\uD0A4 \uC800\uC7A5\uC18C \uC815\uBCF4\uB97C \uC785\uB825\uD558\uC2ED\uC2DC\uC624."},
{"Keystore.alias.","\uD0A4 \uC800\uC7A5\uC18C \uBCC4\uCE6D: "},
{"Keystore.password.","\uD0A4 \uC800\uC7A5\uC18C \uBE44\uBC00\uBC88\uD638: "},
{"Private.key.password.optional.",
"\uC804\uC6A9 \uD0A4 \uBE44\uBC00\uBC88\uD638(\uC120\uD0DD\uC0AC\uD56D): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos \uC0AC\uC6A9\uC790 \uC774\uB984 [{0}]: "},
{"Kerberos.password.for.username.",
"{0}\uC758 Kerberos \uBE44\uBC00\uBC88\uD638: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_pt_BR extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "entrada nula inv\u00E1lida: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "Valor de NTSid inv\u00E1lido"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [Grupo Principal]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [Grupo Complementar]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "N\u00E3o \u00E9 poss\u00EDvel expandir corretamente {0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (tal arquivo ou diret\u00F3rio n\u00E3o existe)"},
{"Configuration.Error.No.such.file.or.directory",
"Erro de Configura\u00E7\u00E3o:\n\tN\u00E3o h\u00E1 tal arquivo ou diret\u00F3rio"},
{"Configuration.Error.Invalid.control.flag.flag",
"Erro de Configura\u00E7\u00E3o:\n\tFlag de controle inv\u00E1lido, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Erro de Configura\u00E7\u00E3o:\n\tN\u00E3o \u00E9 poss\u00EDvel especificar v\u00E1rias entradas para {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Erro de Configura\u00E7\u00E3o:\n\tesperado [{0}], lido [fim do arquivo]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Erro de Configura\u00E7\u00E3o:\n\tLinha {0}: esperada [{1}], encontrada [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"Erro de Configura\u00E7\u00E3o:\n\tLinha {0}: esperada [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Erro de Configura\u00E7\u00E3o:\n\tLinha {0}: propriedade do sistema [{1}] expandida para valor vazio"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","nome do usu\u00E1rio: "},
{"password.","senha: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Especifique as informa\u00E7\u00F5es do armazenamento de chaves"},
{"Keystore.alias.","Alias do armazenamento de chaves: "},
{"Keystore.password.","Senha do armazenamento de chaves: "},
{"Private.key.password.optional.",
"Senha da chave privada (opcional): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Nome do usu\u00E1rio de Kerberos [{0}]: "},
{"Kerberos.password.for.username.",
"Senha de Kerberos de {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_sv extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "ogiltiga null-indata: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "Ogiltigt NTSid-v\u00E4rde"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [prim\u00E4r grupp]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [till\u00E4ggsgrupp]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "Kan inte ut\u00F6ka korrekt {0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (det finns ingen s\u00E5dan fil eller katalog)"},
{"Configuration.Error.No.such.file.or.directory",
"Konfigurationsfel:\n\tFilen eller katalogen finns inte"},
{"Configuration.Error.Invalid.control.flag.flag",
"Konfigurationsfel:\n\tOgiltig kontrollflagga, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"Konfigurationsfel:\n\tKan inte ange flera poster f\u00F6r {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"Konfigurationsfel:\n\tf\u00F6rv\u00E4ntade [{0}], l\u00E4ste [filslut]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"Konfigurationsfel:\n\tRad {0}: f\u00F6rv\u00E4ntade [{1}], hittade [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"Konfigurationsfel:\n\tRad {0}: f\u00F6rv\u00E4ntade [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"Konfigurationsfel:\n\tRad {0}: systemegenskapen [{1}] ut\u00F6kad till tomt v\u00E4rde"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","anv\u00E4ndarnamn: "},
{"password.","l\u00F6senord: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"Ange nyckellagerinformation"},
{"Keystore.alias.","Nyckellageralias: "},
{"Keystore.password.","Nyckellagerl\u00F6senord: "},
{"Private.key.password.optional.",
"L\u00F6senord f\u00F6r personlig nyckel (valfritt): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos-anv\u00E4ndarnamn [{0}]: "},
{"Kerberos.password.for.username.",
"Kerberos-l\u00F6senord f\u00F6r {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_zh_CN extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "\u65E0\u6548\u7684\u7A7A\u8F93\u5165: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "\u65E0\u6548\u7684 NTSid \u503C"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [\u4E3B\u7EC4]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [\u8865\u5145\u7EC4]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "\u65E0\u6CD5\u6B63\u786E\u6269\u5C55{0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (\u6CA1\u6709\u8FD9\u6837\u7684\u6587\u4EF6\u6216\u76EE\u5F55)"},
{"Configuration.Error.No.such.file.or.directory",
"\u914D\u7F6E\u9519\u8BEF:\n\t\u6CA1\u6709\u6B64\u6587\u4EF6\u6216\u76EE\u5F55"},
{"Configuration.Error.Invalid.control.flag.flag",
"\u914D\u7F6E\u9519\u8BEF: \n\t\u65E0\u6548\u7684\u63A7\u5236\u6807\u8BB0, {0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"\u914D\u7F6E\u9519\u8BEF:\n\t\u65E0\u6CD5\u6307\u5B9A{0}\u7684\u591A\u4E2A\u6761\u76EE"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"\u914D\u7F6E\u9519\u8BEF: \n\t\u5E94\u4E3A [{0}], \u8BFB\u53D6\u7684\u662F [\u6587\u4EF6\u7ED3\u5C3E]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"\u914D\u7F6E\u9519\u8BEF: \n\t\u884C {0}: \u5E94\u4E3A [{1}], \u627E\u5230 [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"\u914D\u7F6E\u9519\u8BEF: \n\t\u884C {0}: \u5E94\u4E3A [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"\u914D\u7F6E\u9519\u8BEF: \n\t\u884C {0}: \u7CFB\u7EDF\u5C5E\u6027 [{1}] \u6269\u5C55\u5230\u7A7A\u503C"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","\u7528\u6237\u540D: "},
{"password.","\u53E3\u4EE4: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"\u8BF7\u8F93\u5165\u5BC6\u94A5\u5E93\u4FE1\u606F"},
{"Keystore.alias.","\u5BC6\u94A5\u5E93\u522B\u540D: "},
{"Keystore.password.","\u5BC6\u94A5\u5E93\u53E3\u4EE4: "},
{"Private.key.password.optional.",
"\u79C1\u6709\u5BC6\u94A5\u53E3\u4EE4 (\u53EF\u9009): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos \u7528\u6237\u540D [{0}]: "},
{"Kerberos.password.for.username.",
"{0}\u7684 Kerberos \u53E3\u4EE4: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* <p> This class represents the <code>ResourceBundle</code>
* for the following packages:
*
* <ol>
* <li> com.sun.security.auth
* <li> com.sun.security.auth.login
* </ol>
*
*/
public class AuthResources_zh_TW extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// NT principals
{"invalid.null.input.value", "\u7121\u6548\u7A7A\u503C\u8F38\u5165: {0}"},
{"NTDomainPrincipal.name", "NTDomainPrincipal: {0}"},
{"NTNumericCredential.name", "NTNumericCredential: {0}"},
{"Invalid.NTSid.value", "\u7121\u6548 NTSid \u503C"},
{"NTSid.name", "NTSid: {0}"},
{"NTSidDomainPrincipal.name", "NTSidDomainPrincipal: {0}"},
{"NTSidGroupPrincipal.name", "NTSidGroupPrincipal: {0}"},
{"NTSidPrimaryGroupPrincipal.name", "NTSidPrimaryGroupPrincipal: {0}"},
{"NTSidUserPrincipal.name", "NTSidUserPrincipal: {0}"},
{"NTUserPrincipal.name", "NTUserPrincipal: {0}"},
// UnixPrincipals
{"UnixNumericGroupPrincipal.Primary.Group.name",
"UnixNumericGroupPrincipal [\u4E3B\u7FA4\u7D44]: {0}"},
{"UnixNumericGroupPrincipal.Supplementary.Group.name",
"UnixNumericGroupPrincipal [\u9644\u52A0\u7FA4\u7D44]: {0}"},
{"UnixNumericUserPrincipal.name", "UnixNumericUserPrincipal: {0}"},
{"UnixPrincipal.name", "UnixPrincipal: {0}"},
// com.sun.security.auth.login.ConfigFile
{"Unable.to.properly.expand.config", "\u7121\u6CD5\u9069\u7576\u5730\u64F4\u5145 {0}"},
{"extra.config.No.such.file.or.directory.",
"{0} (\u6C92\u6709\u6B64\u6A94\u6848\u6216\u76EE\u9304)"},
{"Configuration.Error.No.such.file.or.directory",
"\u7D44\u614B\u932F\u8AA4:\n\t\u7121\u6B64\u6A94\u6848\u6216\u76EE\u9304"},
{"Configuration.Error.Invalid.control.flag.flag",
"\u7D44\u614B\u932F\u8AA4:\n\t\u7121\u6548\u7684\u63A7\u5236\u65D7\u6A19\uFF0C{0}"},
{"Configuration.Error.Can.not.specify.multiple.entries.for.appName",
"\u7D44\u614B\u932F\u8AA4: \n\t\u7121\u6CD5\u6307\u5B9A\u591A\u91CD\u9805\u76EE {0}"},
{"Configuration.Error.expected.expect.read.end.of.file.",
"\u7D44\u614B\u932F\u8AA4: \n\t\u9810\u671F\u7684 [{0}], \u8B80\u53D6 [end of file]"},
{"Configuration.Error.Line.line.expected.expect.found.value.",
"\u7D44\u614B\u932F\u8AA4: \n\t\u884C {0}: \u9810\u671F\u7684 [{1}], \u767C\u73FE [{2}]"},
{"Configuration.Error.Line.line.expected.expect.",
"\u7D44\u614B\u932F\u8AA4: \n\t\u884C {0}: \u9810\u671F\u7684 [{1}]"},
{"Configuration.Error.Line.line.system.property.value.expanded.to.empty.value",
"\u7D44\u614B\u932F\u8AA4: \n\t\u884C {0}: \u7CFB\u7D71\u5C6C\u6027 [{1}] \u64F4\u5145\u81F3\u7A7A\u503C"},
// com.sun.security.auth.module.JndiLoginModule
{"username.","\u4F7F\u7528\u8005\u540D\u7A31: "},
{"password.","\u5BC6\u78BC: "},
// com.sun.security.auth.module.KeyStoreLoginModule
{"Please.enter.keystore.information",
"\u8ACB\u8F38\u5165\u91D1\u9470\u5132\u5B58\u5EAB\u8CC7\u8A0A"},
{"Keystore.alias.","\u91D1\u9470\u5132\u5B58\u5EAB\u5225\u540D: "},
{"Keystore.password.","\u91D1\u9470\u5132\u5B58\u5EAB\u5BC6\u78BC: "},
{"Private.key.password.optional.",
"\u79C1\u4EBA\u91D1\u9470\u5BC6\u78BC (\u9078\u64C7\u6027\u7684): "},
// com.sun.security.auth.module.Krb5LoginModule
{"Kerberos.username.defUsername.",
"Kerberos \u4F7F\u7528\u8005\u540D\u7A31 [{0}]: "},
{"Kerberos.password.for.username.",
"Kerberos \u5BC6\u78BC {0}: "},
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* <p>
*
* @return the contents of this <code>ResourceBundle</code>.
*/
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,275 @@
/*
* Copyright (c) 1997, 2006, 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.ByteArrayOutputStream;
import java.util.Arrays;
/**
* A packed array of booleans.
*
* @author Joshua Bloch
* @author Douglas Hoover
*/
public class BitArray {
private byte[] repn;
private int length;
private static final int BITS_PER_UNIT = 8;
private static int subscript(int idx) {
return idx / BITS_PER_UNIT;
}
private static int position(int idx) { // bits big-endian in each unit
return 1 << (BITS_PER_UNIT - 1 - (idx % BITS_PER_UNIT));
}
/**
* Creates a BitArray of the specified size, initialized to zeros.
*/
public BitArray(int length) throws IllegalArgumentException {
if (length < 0) {
throw new IllegalArgumentException("Negative length for BitArray");
}
this.length = length;
repn = new byte[(length + BITS_PER_UNIT - 1)/BITS_PER_UNIT];
}
/**
* Creates a BitArray of the specified size, initialized from the
* specified byte array. The most significant bit of {@code a[0]} gets
* index zero in the BitArray. The array a must be large enough
* to specify a value for every bit in the BitArray. In other words,
* {@code 8*a.length <= length}.
*/
public BitArray(int length, byte[] a) throws IllegalArgumentException {
if (length < 0) {
throw new IllegalArgumentException("Negative length for BitArray");
}
if (a.length * BITS_PER_UNIT < length) {
throw new IllegalArgumentException("Byte array too short to represent " +
"bit array of given length");
}
this.length = length;
int repLength = ((length + BITS_PER_UNIT - 1)/BITS_PER_UNIT);
int unusedBits = repLength*BITS_PER_UNIT - length;
byte bitMask = (byte) (0xFF << unusedBits);
/*
normalize the representation:
1. discard extra bytes
2. zero out extra bits in the last byte
*/
repn = new byte[repLength];
System.arraycopy(a, 0, repn, 0, repLength);
if (repLength > 0) {
repn[repLength - 1] &= bitMask;
}
}
/**
* Create a BitArray whose bits are those of the given array
* of Booleans.
*/
public BitArray(boolean[] bits) {
length = bits.length;
repn = new byte[(length + 7)/8];
for (int i=0; i < length; i++) {
set(i, bits[i]);
}
}
/**
* Copy constructor (for cloning).
*/
private BitArray(BitArray ba) {
length = ba.length;
repn = ba.repn.clone();
}
/**
* Returns the indexed bit in this BitArray.
*/
public boolean get(int index) throws ArrayIndexOutOfBoundsException {
if (index < 0 || index >= length) {
throw new ArrayIndexOutOfBoundsException(Integer.toString(index));
}
return (repn[subscript(index)] & position(index)) != 0;
}
/**
* Sets the indexed bit in this BitArray.
*/
public void set(int index, boolean value)
throws ArrayIndexOutOfBoundsException {
if (index < 0 || index >= length) {
throw new ArrayIndexOutOfBoundsException(Integer.toString(index));
}
int idx = subscript(index);
int bit = position(index);
if (value) {
repn[idx] |= bit;
} else {
repn[idx] &= ~bit;
}
}
/**
* Returns the length of this BitArray.
*/
public int length() {
return length;
}
/**
* Returns a Byte array containing the contents of this BitArray.
* The bit stored at index zero in this BitArray will be copied
* into the most significant bit of the zeroth element of the
* returned byte array. The last byte of the returned byte array
* will be contain zeros in any bits that do not have corresponding
* bits in the BitArray. (This matters only if the BitArray's size
* is not a multiple of 8.)
*/
public byte[] toByteArray() {
return repn.clone();
}
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || !(obj instanceof BitArray)) return false;
BitArray ba = (BitArray) obj;
if (ba.length != length) return false;
for (int i = 0; i < repn.length; i += 1) {
if (repn[i] != ba.repn[i]) return false;
}
return true;
}
/**
* Return a boolean array with the same bit values a this BitArray.
*/
public boolean[] toBooleanArray() {
boolean[] bits = new boolean[length];
for (int i=0; i < length; i++) {
bits[i] = get(i);
}
return bits;
}
/**
* Returns a hash code value for this bit array.
*
* @return a hash code value for this bit array.
*/
public int hashCode() {
int hashCode = 0;
for (int i = 0; i < repn.length; i++)
hashCode = 31*hashCode + repn[i];
return hashCode ^ length;
}
public Object clone() {
return new BitArray(this);
}
private static final byte[][] NYBBLE = {
{ (byte)'0',(byte)'0',(byte)'0',(byte)'0'},
{ (byte)'0',(byte)'0',(byte)'0',(byte)'1'},
{ (byte)'0',(byte)'0',(byte)'1',(byte)'0'},
{ (byte)'0',(byte)'0',(byte)'1',(byte)'1'},
{ (byte)'0',(byte)'1',(byte)'0',(byte)'0'},
{ (byte)'0',(byte)'1',(byte)'0',(byte)'1'},
{ (byte)'0',(byte)'1',(byte)'1',(byte)'0'},
{ (byte)'0',(byte)'1',(byte)'1',(byte)'1'},
{ (byte)'1',(byte)'0',(byte)'0',(byte)'0'},
{ (byte)'1',(byte)'0',(byte)'0',(byte)'1'},
{ (byte)'1',(byte)'0',(byte)'1',(byte)'0'},
{ (byte)'1',(byte)'0',(byte)'1',(byte)'1'},
{ (byte)'1',(byte)'1',(byte)'0',(byte)'0'},
{ (byte)'1',(byte)'1',(byte)'0',(byte)'1'},
{ (byte)'1',(byte)'1',(byte)'1',(byte)'0'},
{ (byte)'1',(byte)'1',(byte)'1',(byte)'1'}
};
private static final int BYTES_PER_LINE = 8;
/**
* Returns a string representation of this BitArray.
*/
public String toString() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int i = 0; i < repn.length - 1; i++) {
out.write(NYBBLE[(repn[i] >> 4) & 0x0F], 0, 4);
out.write(NYBBLE[repn[i] & 0x0F], 0, 4);
if (i % BYTES_PER_LINE == BYTES_PER_LINE - 1) {
out.write('\n');
} else {
out.write(' ');
}
}
// in last byte of repn, use only the valid bits
for (int i = BITS_PER_UNIT * (repn.length - 1); i < length; i++) {
out.write(get(i) ? '1' : '0');
}
return new String(out.toByteArray());
}
public BitArray truncate() {
for (int i=length-1; i>=0; i--) {
if (get(i)) {
return new BitArray(i+1, Arrays.copyOf(repn, (i + BITS_PER_UNIT)/BITS_PER_UNIT));
}
}
return new BitArray(1);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 1997, 2006, 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.util.Comparator;
/**
* Compare two byte arrays in lexicographical order.
*
* @author D. N. Hoover
*/
public class ByteArrayLexOrder implements Comparator<byte[]> {
/**
* Perform lexicographical comparison of two byte arrays,
* regarding each byte as unsigned. That is, compare array entries
* in order until they differ--the array with the smaller entry
* is "smaller". If array entries are
* equal till one array ends, then the longer array is "bigger".
*
* @param bytes1 first byte array to compare.
* @param bytes2 second byte array to compare.
* @return negative number if {@code bytes1 < bytes2},
* 0 if {@code bytes1 == bytes2},
* positive number if {@code bytes1 > bytes2}.
*
* @exception <code>ClassCastException</code>
* if either argument is not a byte array.
*/
public final int compare( byte[] bytes1, byte[] bytes2) {
int diff;
for (int i = 0; i < bytes1.length && i < bytes2.length; i++) {
diff = (bytes1[i] & 0xFF) - (bytes2[i] & 0xFF);
if (diff != 0) {
return diff;
}
}
// if array entries are equal till the first ends, then the
// longer is "bigger"
return bytes1.length - bytes2.length;
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 1997, 2006, 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.
*/
/**
* ByteArrayTagOrder: a class for comparing two DER encodings by the
* order of their tags.
*
* @author D. N. Hoover
*/
package sun.security.util;
import java.util.Comparator;
public class ByteArrayTagOrder implements Comparator<byte[]> {
/**
* Compare two byte arrays, by the order of their tags,
* as defined in ITU-T X.680, sec. 6.4. (First compare
* tag classes, then tag numbers, ignoring the constructivity bit.)
*
* @param bytes1 first byte array to compare.
* @param bytes2 second byte array to compare.
* @return negative number if {@code bytes1 < bytes2},
* 0 if {@code bytes1 == bytes2},
* positive number if {@code bytes1 > bytes2}.
*
* @exception <code>ClassCastException</code>
* if either argument is not a byte array.
*/
public final int compare(byte[] bytes1, byte[] bytes2) {
// tag order is same as byte order ignoring any difference in
// the constructivity bit (0x02)
return (bytes1[0] | 0x20) - (bytes2[0] | 0x20);
}
}

View file

@ -0,0 +1,552 @@
/*
* Copyright (c) 2002, 2011, 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.util.*;
import java.lang.ref.*;
/**
* Abstract base class and factory for caches. A cache is a key-value mapping.
* It has properties that make it more suitable for caching than a Map.
*
* The factory methods can be used to obtain two different implementations.
* They have the following properties:
*
* . keys and values reside in memory
*
* . keys and values must be non-null
*
* . maximum size. Replacements are made in LRU order.
*
* . optional lifetime, specified in seconds.
*
* . safe for concurrent use by multiple threads
*
* . values are held by either standard references or via SoftReferences.
* SoftReferences have the advantage that they are automatically cleared
* by the garbage collector in response to memory demand. This makes it
* possible to simple set the maximum size to a very large value and let
* the GC automatically size the cache dynamically depending on the
* amount of available memory.
*
* However, note that because of the way SoftReferences are implemented in
* HotSpot at the moment, this may not work perfectly as it clears them fairly
* eagerly. Performance may be improved if the Java heap size is set to larger
* value using e.g. java -ms64M -mx128M foo.Test
*
* Cache sizing: the memory cache is implemented on top of a LinkedHashMap.
* In its current implementation, the number of buckets (NOT entries) in
* (Linked)HashMaps is always a power of two. It is recommended to set the
* maximum cache size to value that uses those buckets fully. For example,
* if a cache with somewhere between 500 and 1000 entries is desired, a
* maximum size of 750 would be a good choice: try 1024 buckets, with a
* load factor of 0.75f, the number of entries can be calculated as
* buckets / 4 * 3. As mentioned above, with a SoftReference cache, it is
* generally reasonable to set the size to a fairly large value.
*
* @author Andreas Sterbenz
*/
public abstract class Cache<K,V> {
protected Cache() {
// empty
}
/**
* Return the number of currently valid entries in the cache.
*/
public abstract int size();
/**
* Remove all entries from the cache.
*/
public abstract void clear();
/**
* Add an entry to the cache.
*/
public abstract void put(K key, V value);
/**
* Get a value from the cache.
*/
public abstract V get(Object key);
/**
* Remove an entry from the cache.
*/
public abstract void remove(Object key);
/**
* Set the maximum size.
*/
public abstract void setCapacity(int size);
/**
* Set the timeout(in seconds).
*/
public abstract void setTimeout(int timeout);
/**
* accept a visitor
*/
public abstract void accept(CacheVisitor<K,V> visitor);
/**
* Return a new memory cache with the specified maximum size, unlimited
* lifetime for entries, with the values held by SoftReferences.
*/
public static <K,V> Cache<K,V> newSoftMemoryCache(int size) {
return new MemoryCache<>(true, size);
}
/**
* Return a new memory cache with the specified maximum size, the
* specified maximum lifetime (in seconds), with the values held
* by SoftReferences.
*/
public static <K,V> Cache<K,V> newSoftMemoryCache(int size, int timeout) {
return new MemoryCache<>(true, size, timeout);
}
/**
* Return a new memory cache with the specified maximum size, unlimited
* lifetime for entries, with the values held by standard references.
*/
public static <K,V> Cache<K,V> newHardMemoryCache(int size) {
return new MemoryCache<>(false, size);
}
/**
* Return a dummy cache that does nothing.
*/
@SuppressWarnings("unchecked")
public static <K,V> Cache<K,V> newNullCache() {
return (Cache<K,V>) NullCache.INSTANCE;
}
/**
* Return a new memory cache with the specified maximum size, the
* specified maximum lifetime (in seconds), with the values held
* by standard references.
*/
public static <K,V> Cache<K,V> newHardMemoryCache(int size, int timeout) {
return new MemoryCache<>(false, size, timeout);
}
/**
* Utility class that wraps a byte array and implements the equals()
* and hashCode() contract in a way suitable for Maps and caches.
*/
public static class EqualByteArray {
private final byte[] b;
private volatile int hash;
public EqualByteArray(byte[] b) {
this.b = b;
}
public int hashCode() {
int h = hash;
if (h == 0) {
h = b.length + 1;
for (int i = 0; i < b.length; i++) {
h += (b[i] & 0xff) * 37;
}
hash = h;
}
return h;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof EqualByteArray == false) {
return false;
}
EqualByteArray other = (EqualByteArray)obj;
return Arrays.equals(this.b, other.b);
}
}
public interface CacheVisitor<K,V> {
public void visit(Map<K,V> map);
}
}
class NullCache<K,V> extends Cache<K,V> {
static final Cache<Object,Object> INSTANCE = new NullCache<>();
private NullCache() {
// empty
}
public int size() {
return 0;
}
public void clear() {
// empty
}
public void put(K key, V value) {
// empty
}
public V get(Object key) {
return null;
}
public void remove(Object key) {
// empty
}
public void setCapacity(int size) {
// empty
}
public void setTimeout(int timeout) {
// empty
}
public void accept(CacheVisitor<K,V> visitor) {
// empty
}
}
class MemoryCache<K,V> extends Cache<K,V> {
private static final float LOAD_FACTOR = 0.75f;
// XXXX
private static final boolean DEBUG = false;
private final Map<K, CacheEntry<K,V>> cacheMap;
private int maxSize;
private long lifetime;
// ReferenceQueue is of type V instead of Cache<K,V>
// to allow SoftCacheEntry to extend SoftReference<V>
private final ReferenceQueue<V> queue;
public MemoryCache(boolean soft, int maxSize) {
this(soft, maxSize, 0);
}
public MemoryCache(boolean soft, int maxSize, int lifetime) {
this.maxSize = maxSize;
this.lifetime = lifetime * 1000;
if (soft)
this.queue = new ReferenceQueue<>();
else
this.queue = null;
int buckets = (int)(maxSize / LOAD_FACTOR) + 1;
cacheMap = new LinkedHashMap<>(buckets, LOAD_FACTOR, true);
}
/**
* Empty the reference queue and remove all corresponding entries
* from the cache.
*
* This method should be called at the beginning of each public
* method.
*/
private void emptyQueue() {
if (queue == null) {
return;
}
int startSize = cacheMap.size();
while (true) {
@SuppressWarnings("unchecked")
CacheEntry<K,V> entry = (CacheEntry<K,V>)queue.poll();
if (entry == null) {
break;
}
K key = entry.getKey();
if (key == null) {
// key is null, entry has already been removed
continue;
}
CacheEntry<K,V> currentEntry = cacheMap.remove(key);
// check if the entry in the map corresponds to the expired
// entry. If not, readd the entry
if ((currentEntry != null) && (entry != currentEntry)) {
cacheMap.put(key, currentEntry);
}
}
if (DEBUG) {
int endSize = cacheMap.size();
if (startSize != endSize) {
System.out.println("*** Expunged " + (startSize - endSize)
+ " entries, " + endSize + " entries left");
}
}
}
/**
* Scan all entries and remove all expired ones.
*/
private void expungeExpiredEntries() {
emptyQueue();
if (lifetime == 0) {
return;
}
int cnt = 0;
long time = System.currentTimeMillis();
for (Iterator<CacheEntry<K,V>> t = cacheMap.values().iterator();
t.hasNext(); ) {
CacheEntry<K,V> entry = t.next();
if (entry.isValid(time) == false) {
t.remove();
cnt++;
}
}
if (DEBUG) {
if (cnt != 0) {
System.out.println("Removed " + cnt
+ " expired entries, remaining " + cacheMap.size());
}
}
}
public synchronized int size() {
expungeExpiredEntries();
return cacheMap.size();
}
public synchronized void clear() {
if (queue != null) {
// if this is a SoftReference cache, first invalidate() all
// entries so that GC does not have to enqueue them
for (CacheEntry<K,V> entry : cacheMap.values()) {
entry.invalidate();
}
while (queue.poll() != null) {
// empty
}
}
cacheMap.clear();
}
public synchronized void put(K key, V value) {
emptyQueue();
long expirationTime = (lifetime == 0) ? 0 :
System.currentTimeMillis() + lifetime;
CacheEntry<K,V> newEntry = newEntry(key, value, expirationTime, queue);
CacheEntry<K,V> oldEntry = cacheMap.put(key, newEntry);
if (oldEntry != null) {
oldEntry.invalidate();
return;
}
if (maxSize > 0 && cacheMap.size() > maxSize) {
expungeExpiredEntries();
if (cacheMap.size() > maxSize) { // still too large?
Iterator<CacheEntry<K,V>> t = cacheMap.values().iterator();
CacheEntry<K,V> lruEntry = t.next();
if (DEBUG) {
System.out.println("** Overflow removal "
+ lruEntry.getKey() + " | " + lruEntry.getValue());
}
t.remove();
lruEntry.invalidate();
}
}
}
public synchronized V get(Object key) {
emptyQueue();
CacheEntry<K,V> entry = cacheMap.get(key);
if (entry == null) {
return null;
}
long time = (lifetime == 0) ? 0 : System.currentTimeMillis();
if (entry.isValid(time) == false) {
if (DEBUG) {
System.out.println("Ignoring expired entry");
}
cacheMap.remove(key);
return null;
}
return entry.getValue();
}
public synchronized void remove(Object key) {
emptyQueue();
CacheEntry<K,V> entry = cacheMap.remove(key);
if (entry != null) {
entry.invalidate();
}
}
public synchronized void setCapacity(int size) {
expungeExpiredEntries();
if (size > 0 && cacheMap.size() > size) {
Iterator<CacheEntry<K,V>> t = cacheMap.values().iterator();
for (int i = cacheMap.size() - size; i > 0; i--) {
CacheEntry<K,V> lruEntry = t.next();
if (DEBUG) {
System.out.println("** capacity reset removal "
+ lruEntry.getKey() + " | " + lruEntry.getValue());
}
t.remove();
lruEntry.invalidate();
}
}
maxSize = size > 0 ? size : 0;
if (DEBUG) {
System.out.println("** capacity reset to " + size);
}
}
public synchronized void setTimeout(int timeout) {
emptyQueue();
lifetime = timeout > 0 ? timeout * 1000L : 0L;
if (DEBUG) {
System.out.println("** lifetime reset to " + timeout);
}
}
// it is a heavyweight method.
public synchronized void accept(CacheVisitor<K,V> visitor) {
expungeExpiredEntries();
Map<K,V> cached = getCachedEntries();
visitor.visit(cached);
}
private Map<K,V> getCachedEntries() {
Map<K,V> kvmap = new HashMap<>(cacheMap.size());
for (CacheEntry<K,V> entry : cacheMap.values()) {
kvmap.put(entry.getKey(), entry.getValue());
}
return kvmap;
}
protected CacheEntry<K,V> newEntry(K key, V value,
long expirationTime, ReferenceQueue<V> queue) {
if (queue != null) {
return new SoftCacheEntry<>(key, value, expirationTime, queue);
} else {
return new HardCacheEntry<>(key, value, expirationTime);
}
}
private static interface CacheEntry<K,V> {
boolean isValid(long currentTime);
void invalidate();
K getKey();
V getValue();
}
private static class HardCacheEntry<K,V> implements CacheEntry<K,V> {
private K key;
private V value;
private long expirationTime;
HardCacheEntry(K key, V value, long expirationTime) {
this.key = key;
this.value = value;
this.expirationTime = expirationTime;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public boolean isValid(long currentTime) {
boolean valid = (currentTime <= expirationTime);
if (valid == false) {
invalidate();
}
return valid;
}
public void invalidate() {
key = null;
value = null;
expirationTime = -1;
}
}
private static class SoftCacheEntry<K,V>
extends SoftReference<V>
implements CacheEntry<K,V> {
private K key;
private long expirationTime;
SoftCacheEntry(K key, V value, long expirationTime,
ReferenceQueue<V> queue) {
super(value, queue);
this.key = key;
this.expirationTime = expirationTime;
}
public K getKey() {
return key;
}
public V getValue() {
return get();
}
public boolean isValid(long currentTime) {
boolean valid = (currentTime <= expirationTime) && (get() != null);
if (valid == false) {
invalidate();
}
return valid;
}
public void invalidate() {
clear();
key = null;
expirationTime = -1;
}
}
}

View file

@ -0,0 +1,247 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.ConfirmationCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* A {@code CallbackHandler} that prompts and reads from the command line
* for answers to authentication questions.
*/
public class ConsoleCallbackHandler implements CallbackHandler {
/**
* Creates a callback handler that prompts and reads from the
* command line for answers to authentication questions.
*/
public ConsoleCallbackHandler() { }
/**
* Handles the specified set of callbacks.
*
* @param callbacks the callbacks to handle
* @throws IOException if an input or output error occurs.
* @throws UnsupportedCallbackException if the callback is not an
* instance of NameCallback or PasswordCallback
*/
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException
{
ConfirmationCallback confirmation = null;
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
TextOutputCallback tc = (TextOutputCallback) callbacks[i];
String text;
switch (tc.getMessageType()) {
case TextOutputCallback.INFORMATION:
text = "";
break;
case TextOutputCallback.WARNING:
text = "Warning: ";
break;
case TextOutputCallback.ERROR:
text = "Error: ";
break;
default:
throw new UnsupportedCallbackException(
callbacks[i], "Unrecognized message type");
}
String message = tc.getMessage();
if (message != null) {
text += message;
}
if (text != null) {
System.err.println(text);
}
} else if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks[i];
if (nc.getDefaultName() == null) {
System.err.print(nc.getPrompt());
} else {
System.err.print(nc.getPrompt() +
" [" + nc.getDefaultName() + "] ");
}
System.err.flush();
String result = readLine();
if (result.equals("")) {
result = nc.getDefaultName();
}
nc.setName(result);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks[i];
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(Password.readPassword(System.in, pc.isEchoOn()));
} else if (callbacks[i] instanceof ConfirmationCallback) {
confirmation = (ConfirmationCallback) callbacks[i];
} else {
throw new UnsupportedCallbackException(
callbacks[i], "Unrecognized Callback");
}
}
/* Do the confirmation callback last. */
if (confirmation != null) {
doConfirmation(confirmation);
}
}
/* Reads a line of input */
private String readLine() throws IOException {
String result = new BufferedReader
(new InputStreamReader(System.in)).readLine();
if (result == null) {
throw new IOException("Cannot read from System.in");
}
return result;
}
private void doConfirmation(ConfirmationCallback confirmation)
throws IOException, UnsupportedCallbackException
{
String prefix;
int messageType = confirmation.getMessageType();
switch (messageType) {
case ConfirmationCallback.WARNING:
prefix = "Warning: ";
break;
case ConfirmationCallback.ERROR:
prefix = "Error: ";
break;
case ConfirmationCallback.INFORMATION:
prefix = "";
break;
default:
throw new UnsupportedCallbackException(
confirmation, "Unrecognized message type: " + messageType);
}
class OptionInfo {
String name;
int value;
OptionInfo(String name, int value) {
this.name = name;
this.value = value;
}
}
OptionInfo[] options;
int optionType = confirmation.getOptionType();
switch (optionType) {
case ConfirmationCallback.YES_NO_OPTION:
options = new OptionInfo[] {
new OptionInfo("Yes", ConfirmationCallback.YES),
new OptionInfo("No", ConfirmationCallback.NO)
};
break;
case ConfirmationCallback.YES_NO_CANCEL_OPTION:
options = new OptionInfo[] {
new OptionInfo("Yes", ConfirmationCallback.YES),
new OptionInfo("No", ConfirmationCallback.NO),
new OptionInfo("Cancel", ConfirmationCallback.CANCEL)
};
break;
case ConfirmationCallback.OK_CANCEL_OPTION:
options = new OptionInfo[] {
new OptionInfo("OK", ConfirmationCallback.OK),
new OptionInfo("Cancel", ConfirmationCallback.CANCEL)
};
break;
case ConfirmationCallback.UNSPECIFIED_OPTION:
String[] optionStrings = confirmation.getOptions();
options = new OptionInfo[optionStrings.length];
for (int i = 0; i < options.length; i++) {
options[i] = new OptionInfo(optionStrings[i], i);
}
break;
default:
throw new UnsupportedCallbackException(
confirmation, "Unrecognized option type: " + optionType);
}
int defaultOption = confirmation.getDefaultOption();
String prompt = confirmation.getPrompt();
if (prompt == null) {
prompt = "";
}
prompt = prefix + prompt;
if (!prompt.equals("")) {
System.err.println(prompt);
}
for (int i = 0; i < options.length; i++) {
if (optionType == ConfirmationCallback.UNSPECIFIED_OPTION) {
// defaultOption is an index into the options array
System.err.println(
i + ". " + options[i].name +
(i == defaultOption ? " [default]" : ""));
} else {
// defaultOption is an option value
System.err.println(
i + ". " + options[i].name +
(options[i].value == defaultOption ? " [default]" : ""));
}
}
System.err.print("Enter a number: ");
System.err.flush();
int result;
try {
result = Integer.parseInt(readLine());
if (result < 0 || result > (options.length - 1)) {
result = defaultOption;
}
result = options[result].value;
} catch (NumberFormatException e) {
result = defaultOption;
}
confirmation.setSelectedIndex(result);
}
}

View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import sun.security.validator.Validator;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Timestamp;
import java.security.cert.X509Certificate;
import java.util.Date;
/**
* This class contains parameters for checking against constraints that extend
* past the publicly available parameters in java.security.AlgorithmConstraints.
* This is currently on passed between between PKIX, AlgorithmChecker,
* and DisabledAlgorithmConstraints.
*/
public class ConstraintsParameters {
/*
* The below 3 values are used the same as the permit() methods
* published in java.security.AlgorithmConstraints.
*/
// Algorithm string to be checked against constraints
private final String algorithm;
// AlgorithmParameters to the algorithm being checked
private final AlgorithmParameters algParams;
// Public Key being checked against constraints
private final Key publicKey;
/*
* New values that are checked against constraints that the current public
* API does not support.
*/
// A certificate being passed to check against constraints.
private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates
private final boolean trustedMatch;
// PKIXParameter date
private final Date pkixDate;
// Timestamp of the signed JAR file
private final Timestamp jarTimestamp;
private final String variant;
public ConstraintsParameters(X509Certificate c, boolean match,
Date pkixdate, Timestamp jarTime, String variant) {
cert = c;
trustedMatch = match;
pkixDate = pkixdate;
jarTimestamp = jarTime;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
algorithm = null;
algParams = null;
publicKey = null;
}
public ConstraintsParameters(String algorithm, AlgorithmParameters params,
Key key, String variant) {
this.algorithm = algorithm;
algParams = params;
this.publicKey = key;
cert = null;
trustedMatch = false;
pkixDate = null;
jarTimestamp = null;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
public ConstraintsParameters(X509Certificate c) {
this(c, false, null, null,
Validator.VAR_GENERIC);
}
public ConstraintsParameters(Timestamp jarTime) {
this(null, false, null, jarTime, Validator.VAR_GENERIC);
}
public String getAlgorithm() {
return algorithm;
}
public AlgorithmParameters getAlgParams() {
return algParams;
}
public Key getPublicKey() {
return publicKey;
}
// Returns if the trust anchor has a match if anchor checking is enabled.
public boolean isTrustedMatch() {
return trustedMatch;
}
public X509Certificate getCertificate() {
return cert;
}
public Date getPKIXParamDate() {
return pkixDate;
}
public Timestamp getJARTimestamp() {
return jarTimestamp;
}
public String getVariant() {
return variant;
}
}

View file

@ -0,0 +1,737 @@
/*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.math.BigInteger;
import java.security.spec.*;
import java.util.*;
import java.util.regex.Pattern;
/**
* Repository for well-known Elliptic Curve parameters. It is used by both
* the SunPKCS11 and SunJSSE code.
*
* @since 1.6
* @author Andreas Sterbenz
*/
public class CurveDB {
private static final int P = 1; // prime curve
private static final int B = 2; // binary curve
private static final int PD = 5; // prime curve, mark as default
private static final int BD = 6; // binary curve, mark as default
private static final Map<String,NamedCurve> oidMap =
new LinkedHashMap<String,NamedCurve>();
private static final Map<String,NamedCurve> nameMap =
new HashMap<String,NamedCurve>();
private static final Map<Integer,NamedCurve> lengthMap =
new HashMap<Integer,NamedCurve>();
private static Collection<? extends NamedCurve> specCollection;
public static final String SPLIT_PATTERN = ",|\\[|\\]";
// Used by SunECEntries
public static Collection<? extends NamedCurve>getSupportedCurves() {
return specCollection;
}
// Return a NamedCurve for the specified OID/name or null if unknown.
static NamedCurve lookup(String name) {
NamedCurve spec = oidMap.get(name);
if (spec != null) {
return spec;
}
return nameMap.get(name);
}
// Return EC parameters for the specified field size. If there are known
// NIST recommended parameters for the given length, they are returned.
// Otherwise, if there are multiple matches for the given size, an
// arbitrary one is returns.
// If no parameters are known, the method returns null.
// NOTE that this method returns both prime and binary curves.
static NamedCurve lookup(int length) {
return lengthMap.get(length);
}
// Convert the given ECParameterSpec object to a NamedCurve object.
// If params does not represent a known named curve, return null.
static NamedCurve lookup(ECParameterSpec params) {
if ((params instanceof NamedCurve) || (params == null)) {
return (NamedCurve)params;
}
// This is a hack to allow SunJSSE to work with 3rd party crypto
// providers for ECC and not just SunPKCS11.
// This can go away once we decide how to expose curve names in the
// public API.
// Note that it assumes that the 3rd party provider encodes named
// curves using the short form, not explicitly. If it did that, then
// the SunJSSE TLS ECC extensions are wrong, which could lead to
// interoperability problems.
int fieldSize = params.getCurve().getField().getFieldSize();
for (NamedCurve namedCurve : specCollection) {
// ECParameterSpec does not define equals, so check all the
// components ourselves.
// Quick field size check first
if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) {
continue;
}
if (namedCurve.getCurve().equals(params.getCurve()) == false) {
continue;
}
if (namedCurve.getGenerator().equals(params.getGenerator()) ==
false) {
continue;
}
if (namedCurve.getOrder().equals(params.getOrder()) == false) {
continue;
}
if (namedCurve.getCofactor() != params.getCofactor()) {
continue;
}
// everything matches our named curve, return it
return namedCurve;
}
// no match found
return null;
}
private static BigInteger bi(String s) {
return new BigInteger(s, 16);
}
private static void add(String name, String soid, int type, String sfield,
String a, String b, String x, String y, String n, int h,
Pattern nameSplitPattern) {
BigInteger p = bi(sfield);
ECField field;
if ((type == P) || (type == PD)) {
field = new ECFieldFp(p);
} else if ((type == B) || (type == BD)) {
field = new ECFieldF2m(p.bitLength() - 1, p);
} else {
throw new RuntimeException("Invalid type: " + type);
}
EllipticCurve curve = new EllipticCurve(field, bi(a), bi(b));
ECPoint g = new ECPoint(bi(x), bi(y));
NamedCurve params = new NamedCurve(name, soid, curve, g, bi(n), h);
if (oidMap.put(soid, params) != null) {
throw new RuntimeException("Duplication oid: " + soid);
}
String[] commonNames = nameSplitPattern.split(name);
for (String commonName : commonNames) {
if (nameMap.put(commonName.trim(), params) != null) {
throw new RuntimeException("Duplication name: " + commonName);
}
}
int len = field.getFieldSize();
if ((type == PD) || (type == BD) || (lengthMap.get(len) == null)) {
// add entry if none present for this field size or if
// the curve is marked as a default curve.
lengthMap.put(len, params);
}
}
static {
Pattern nameSplitPattern = Pattern.compile(SPLIT_PATTERN);
/* SEC2 prime curves */
add("secp112r1", "1.3.132.0.6", P,
"DB7C2ABF62E35E668076BEAD208B",
"DB7C2ABF62E35E668076BEAD2088",
"659EF8BA043916EEDE8911702B22",
"09487239995A5EE76B55F9C2F098",
"A89CE5AF8724C0A23E0E0FF77500",
"DB7C2ABF62E35E7628DFAC6561C5",
1, nameSplitPattern);
add("secp112r2", "1.3.132.0.7", P,
"DB7C2ABF62E35E668076BEAD208B",
"6127C24C05F38A0AAAF65C0EF02C",
"51DEF1815DB5ED74FCC34C85D709",
"4BA30AB5E892B4E1649DD0928643",
"adcd46f5882e3747def36e956e97",
"36DF0AAFD8B8D7597CA10520D04B",
4, nameSplitPattern);
add("secp128r1", "1.3.132.0.28", P,
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
"E87579C11079F43DD824993C2CEE5ED3",
"161FF7528B899B2D0C28607CA52C5B86",
"CF5AC8395BAFEB13C02DA292DDED7A83",
"FFFFFFFE0000000075A30D1B9038A115",
1, nameSplitPattern);
add("secp128r2", "1.3.132.0.29", P,
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
"D6031998D1B3BBFEBF59CC9BBFF9AEE1",
"5EEEFCA380D02919DC2C6558BB6D8A5D",
"7B6AA5D85E572983E6FB32A7CDEBC140",
"27B6916A894D3AEE7106FE805FC34B44",
"3FFFFFFF7FFFFFFFBE0024720613B5A3",
4, nameSplitPattern);
add("secp160k1", "1.3.132.0.9", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000007",
"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
"938CF935318FDCED6BC28286531733C3F03C4FEE",
"0100000000000000000001B8FA16DFAB9ACA16B6B3",
1, nameSplitPattern);
add("secp160r1", "1.3.132.0.8", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
"4A96B5688EF573284664698968C38BB913CBFC82",
"23A628553168947D59DCC912042351377AC5FB32",
"0100000000000000000001F4C8F927AED3CA752257",
1, nameSplitPattern);
add("secp160r2", "1.3.132.0.30", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
"B4E134D3FB59EB8BAB57274904664D5AF50388BA",
"52DCB034293A117E1F4FF11B30F7199D3144CE6D",
"FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
"0100000000000000000000351EE786A818F3A1A16B",
1, nameSplitPattern);
add("secp192k1", "1.3.132.0.31", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
"000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000003",
"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
1, nameSplitPattern);
add("secp192r1 [NIST P-192, X9.62 prime192v1]", "1.2.840.10045.3.1.1", PD,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
1, nameSplitPattern);
add("secp224k1", "1.3.132.0.32", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
"00000000000000000000000000000000000000000000000000000000",
"00000000000000000000000000000000000000000000000000000005",
"A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
"7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
"010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
1, nameSplitPattern);
add("secp224r1 [NIST P-224]", "1.3.132.0.33", PD,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1, nameSplitPattern);
add("secp256k1", "1.3.132.0.10", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
"0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000007",
"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
1, nameSplitPattern);
add("secp256r1 [NIST P-256, X9.62 prime256v1]", "1.2.840.10045.3.1.7", PD,
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
1, nameSplitPattern);
add("secp384r1 [NIST P-384]", "1.3.132.0.34", PD,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
"3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
1, nameSplitPattern);
add("secp521r1 [NIST P-521]", "1.3.132.0.35", PD,
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
"0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
"00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
"011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
1, nameSplitPattern);
/* ANSI X9.62 prime curves */
add("X9.62 prime192v2", "1.2.840.10045.3.1.2", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
"CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
"EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
"6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
"FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
1, nameSplitPattern);
add("X9.62 prime192v3", "1.2.840.10045.3.1.3", P,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
"22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
"7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
"38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
"FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
1, nameSplitPattern);
add("X9.62 prime239v1", "1.2.840.10045.3.1.4", P,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
"6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
"0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
"7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
1, nameSplitPattern);
add("X9.62 prime239v2", "1.2.840.10045.3.1.5", P,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
"617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
"38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
"5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
"7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
1, nameSplitPattern);
add("X9.62 prime239v3", "1.2.840.10045.3.1.6", P,
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
"255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
"6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
"1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
1, nameSplitPattern);
/* SEC2 binary curves */
add("sect113r1", "1.3.132.0.4", B,
"020000000000000000000000000201",
"003088250CA6E7C7FE649CE85820F7",
"00E8BEE4D3E2260744188BE0E9C723",
"009D73616F35F4AB1407D73562C10F",
"00A52830277958EE84D1315ED31886",
"0100000000000000D9CCEC8A39E56F",
2, nameSplitPattern);
add("sect113r2", "1.3.132.0.5", B,
"020000000000000000000000000201",
"00689918DBEC7E5A0DD6DFC0AA55C7",
"0095E9A9EC9B297BD4BF36E059184F",
"01A57A6A7B26CA5EF52FCDB8164797",
"00B3ADC94ED1FE674C06E695BABA1D",
"010000000000000108789B2496AF93",
2, nameSplitPattern);
add("sect131r1", "1.3.132.0.22", B,
"080000000000000000000000000000010D",
"07A11B09A76B562144418FF3FF8C2570B8",
"0217C05610884B63B9C6C7291678F9D341",
"0081BAF91FDF9833C40F9C181343638399",
"078C6E7EA38C001F73C8134B1B4EF9E150",
"0400000000000000023123953A9464B54D",
2, nameSplitPattern);
add("sect131r2", "1.3.132.0.23", B,
"080000000000000000000000000000010D",
"03E5A88919D7CAFCBF415F07C2176573B2",
"04B8266A46C55657AC734CE38F018F2192",
"0356DCD8F2F95031AD652D23951BB366A8",
"0648F06D867940A5366D9E265DE9EB240F",
"0400000000000000016954A233049BA98F",
2, nameSplitPattern);
add("sect163k1 [NIST K-163]", "1.3.132.0.1", BD,
"0800000000000000000000000000000000000000C9",
"000000000000000000000000000000000000000001",
"000000000000000000000000000000000000000001",
"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
"04000000000000000000020108A2E0CC0D99F8A5EF",
2, nameSplitPattern);
add("sect163r1", "1.3.132.0.2", B,
"0800000000000000000000000000000000000000C9",
"07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
"0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
"0369979697AB43897789566789567F787A7876A654",
"00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
"03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B",
2, nameSplitPattern);
add("sect163r2 [NIST B-163]", "1.3.132.0.15", BD,
"0800000000000000000000000000000000000000C9",
"000000000000000000000000000000000000000001",
"020A601907B8C953CA1481EB10512F78744A3205FD",
"03F0EBA16286A2D57EA0991168D4994637E8343E36",
"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
"040000000000000000000292FE77E70C12A4234C33",
2, nameSplitPattern);
add("sect193r1", "1.3.132.0.24", B,
"02000000000000000000000000000000000000000000008001",
"0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
"00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
"01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
"0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
"01000000000000000000000000C7F34A778F443ACC920EBA49",
2, nameSplitPattern);
add("sect193r2", "1.3.132.0.25", B,
"02000000000000000000000000000000000000000000008001",
"0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
"00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
"00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
"01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
"010000000000000000000000015AAB561B005413CCD4EE99D5",
2, nameSplitPattern);
add("sect233k1 [NIST K-233]", "1.3.132.0.26", BD,
"020000000000000000000000000000000000000004000000000000000001",
"000000000000000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000000000000000001",
"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
4, nameSplitPattern);
add("sect233r1 [NIST B-233]", "1.3.132.0.27", B,
"020000000000000000000000000000000000000004000000000000000001",
"000000000000000000000000000000000000000000000000000000000001",
"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
2, nameSplitPattern);
add("sect239k1", "1.3.132.0.3", B,
"800000000000000000004000000000000000000000000000000000000001",
"000000000000000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000000000000000001",
"29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
"76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
"2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5",
4, nameSplitPattern);
add("sect283k1 [NIST K-283]", "1.3.132.0.16", BD,
"0800000000000000000000000000000000000000000000000000000000000000000010A1",
"000000000000000000000000000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000000000000000000000000000001",
"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
4, nameSplitPattern);
add("sect283r1 [NIST B-283]", "1.3.132.0.17", B,
"0800000000000000000000000000000000000000000000000000000000000000000010A1",
"000000000000000000000000000000000000000000000000000000000000000000000001",
"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
2, nameSplitPattern);
add("sect409k1 [NIST K-409]", "1.3.132.0.36", BD,
"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
4, nameSplitPattern);
add("sect409r1 [NIST B-409]", "1.3.132.0.37", B,
"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
"010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
2, nameSplitPattern);
add("sect571k1 [NIST K-571]", "1.3.132.0.38", BD,
"080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
"020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
4, nameSplitPattern);
add("sect571r1 [NIST B-571]", "1.3.132.0.39", B,
"080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
2, nameSplitPattern);
/* ANSI X9.62 binary curves */
add("X9.62 c2tnb191v1", "1.2.840.10045.3.0.5", B,
"800000000000000000000000000000000000000000000201",
"2866537B676752636A68F56554E12640276B649EF7526267",
"2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
"36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
"765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
"40000000000000000000000004A20E90C39067C893BBB9A5",
2, nameSplitPattern);
add("X9.62 c2tnb191v2", "1.2.840.10045.3.0.6", B,
"800000000000000000000000000000000000000000000201",
"401028774D7777C7B7666D1366EA432071274F89FF01E718",
"0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
"3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
"17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
"20000000000000000000000050508CB89F652824E06B8173",
4, nameSplitPattern);
add("X9.62 c2tnb191v3", "1.2.840.10045.3.0.7", B,
"800000000000000000000000000000000000000000000201",
"6C01074756099122221056911C77D77E77A777E7E7E77FCB",
"71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
"375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
"545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
"155555555555555555555555610C0B196812BFB6288A3EA3",
6, nameSplitPattern);
add("X9.62 c2tnb239v1", "1.2.840.10045.3.0.11", B,
"800000000000000000000000000000000000000000000000001000000001",
"32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
"790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
"57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
"61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
"2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447",
4, nameSplitPattern);
add("X9.62 c2tnb239v2", "1.2.840.10045.3.0.12", B,
"800000000000000000000000000000000000000000000000001000000001",
"4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
"5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
"28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
"5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
"1555555555555555555555555555553C6F2885259C31E3FCDF154624522D",
6, nameSplitPattern);
add("X9.62 c2tnb239v3", "1.2.840.10045.3.0.13", B,
"800000000000000000000000000000000000000000000000001000000001",
"01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
"6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
"70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
"2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
"0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF",
0xA, nameSplitPattern);
add("X9.62 c2tnb359v1", "1.2.840.10045.3.0.18", B,
"800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
"5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
"2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
"3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
"53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
"01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B",
0x4C, nameSplitPattern);
add("X9.62 c2tnb431r1", "1.2.840.10045.3.0.20", B,
"800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
"1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
"10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
"120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
"20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
"0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91",
0x2760, nameSplitPattern);
/* ANSI X9.62 binary curves from the 1998 standard but forbidden
* in the 2005 version of the standard.
* We don't register them but leave them here for the time being in
* case we need to support them after all.
*/
/*
add("X9.62 c2pnb163v1", "1.2.840.10045.3.0.1", B,
"080000000000000000000000000000000000000107",
"072546B5435234A422E0789675F432C89435DE5242",
"00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
"07AF69989546103D79329FCC3D74880F33BBE803CB",
"01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
"0400000000000000000001E60FC8821CC74DAEAFC1",
2, nameSplitPattern);
add("X9.62 c2pnb163v2", "1.2.840.10045.3.0.2", B,
"080000000000000000000000000000000000000107",
"0108B39E77C4B108BED981ED0E890E117C511CF072",
"0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
"0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
"079F684DDF6684C5CD258B3890021B2386DFD19FC5",
"03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7",
2, nameSplitPattern);
add("X9.62 c2pnb163v3", "1.2.840.10045.3.0.3", B,
"080000000000000000000000000000000000000107",
"07A526C63D3E25A256A007699F5447E32AE456B50E",
"03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
"02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
"05B935590C155E17EA48EB3FF3718B893DF59A05D0",
"03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309",
2, nameSplitPattern);
add("X9.62 c2pnb176w1", "1.2.840.10045.3.0.4", B,
"0100000000000000000000000000000000080000000007",
"E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
"5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
"8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
"6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
"00010092537397ECA4F6145799D62B0A19CE06FE26AD",
0xFF6E, nameSplitPattern);
add("X9.62 c2pnb208w1", "1.2.840.10045.3.0.10", B,
"010000000000000000000000000000000800000000000000000007",
"0000000000000000000000000000000000000000000000000000",
"C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
"89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
"0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
"000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D",
0xFE48, nameSplitPattern);
add("X9.62 c2pnb272w1", "1.2.840.10045.3.0.16", B,
"010000000000000000000000000000000000000000000000000000010000000000000B",
"91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
"7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
"6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
"10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
"000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
0xFF06, nameSplitPattern);
add("X9.62 c2pnb304w1", "1.2.840.10045.3.0.17", B,
"010000000000000000000000000000000000000000000000000000000000000000000000000807",
"FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
"BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
"197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
"E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
"000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D",
0xFE2E, nameSplitPattern);
add("X9.62 c2pnb368w1", "1.2.840.10045.3.0.19", B,
"0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
"E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
"FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
"1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
"7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
"00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967",
0xFF70, nameSplitPattern);
*/
/*
* Brainpool curves (RFC 5639)
* (Twisted curves are not included)
*/
add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P,
"E95E4A5F737059DC60DFC7AD95B3D8139515620F",
"340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
"1E589A8595423412134FAA2DBDEC95C8D8675E58",
"BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
"1667CB477A1A8EC338F94741669C976316DA6321",
"E95E4A5F737059DC60DF5991D45029409E60FC09",
1, nameSplitPattern);
add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P,
"C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
"6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
"469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
"C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
"14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
"C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
1, nameSplitPattern);
add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P,
"D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
"68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
"2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
"0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
"58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
"D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
1, nameSplitPattern);
add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P,
"A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
"7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
"26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
"8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
"547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
1, nameSplitPattern);
add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P,
"D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
"3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
"520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
"43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
"14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
"D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
1, nameSplitPattern);
add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P,
"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
"7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
"04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
"1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
"8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
1, nameSplitPattern);
add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P,
"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
"7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
"3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
"81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
"7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
1, nameSplitPattern);
specCollection = Collections.unmodifiableCollection(oidMap.values());
}
}

View file

@ -0,0 +1,339 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.PrintStream;
import java.math.BigInteger;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Locale;
import sun.security.action.GetPropertyAction;
/**
* A utility class for debugging.
*
* @author Roland Schemers
*/
public class Debug {
private String prefix;
private static String args;
static {
args = GetPropertyAction.privilegedGetProperty("java.security.debug");
String args2 = GetPropertyAction
.privilegedGetProperty("java.security.auth.debug");
if (args == null) {
args = args2;
} else {
if (args2 != null)
args = args + "," + args2;
}
if (args != null) {
args = marshal(args);
if (args.equals("help")) {
Help();
}
}
}
public static void Help()
{
System.err.println();
System.err.println("all turn on all debugging");
System.err.println("access print all checkPermission results");
System.err.println("certpath PKIX CertPathBuilder and");
System.err.println(" CertPathValidator debugging");
System.err.println("combiner SubjectDomainCombiner debugging");
System.err.println("gssloginconfig");
System.err.println(" GSS LoginConfigImpl debugging");
System.err.println("configfile JAAS ConfigFile loading");
System.err.println("configparser JAAS ConfigFile parsing");
System.err.println("jar jar verification");
System.err.println("logincontext login context results");
System.err.println("jca JCA engine class debugging");
System.err.println("keystore KeyStore debugging");
System.err.println("policy loading and granting");
System.err.println("provider security provider debugging");
System.err.println("pkcs11 PKCS11 session manager debugging");
System.err.println("pkcs11keystore");
System.err.println(" PKCS11 KeyStore debugging");
System.err.println("pkcs12 PKCS12 KeyStore debugging");
System.err.println("sunpkcs11 SunPKCS11 provider debugging");
System.err.println("scl permissions SecureClassLoader assigns");
System.err.println("securerandom SecureRandom");
System.err.println("ts timestamping");
System.err.println();
System.err.println("The following can be used with access:");
System.err.println();
System.err.println("stack include stack trace");
System.err.println("domain dump all domains in context");
System.err.println("failure before throwing exception, dump stack");
System.err.println(" and domain that didn't have permission");
System.err.println();
System.err.println("The following can be used with stack and domain:");
System.err.println();
System.err.println("permission=<classname>");
System.err.println(" only dump output if specified permission");
System.err.println(" is being checked");
System.err.println("codebase=<URL>");
System.err.println(" only dump output if specified codebase");
System.err.println(" is being checked");
System.err.println();
System.err.println("The following can be used with provider:");
System.err.println();
System.err.println("engine=<engines>");
System.err.println(" only dump output for the specified list");
System.err.println(" of JCA engines. Supported values:");
System.err.println(" Cipher, KeyAgreement, KeyGenerator,");
System.err.println(" KeyPairGenerator, KeyStore, Mac,");
System.err.println(" MessageDigest, SecureRandom, Signature.");
System.err.println();
System.err.println("The following can be used with certpath:");
System.err.println();
System.err.println("ocsp dump the OCSP protocol exchanges");
System.err.println("verbose verbose debugging");
System.err.println();
System.err.println("Note: Separate multiple options with a comma");
System.exit(0);
}
/**
* Get a Debug object corresponding to whether or not the given
* option is set. Set the prefix to be the same as option.
*/
public static Debug getInstance(String option)
{
return getInstance(option, option);
}
/**
* Get a Debug object corresponding to whether or not the given
* option is set. Set the prefix to be prefix.
*/
public static Debug getInstance(String option, String prefix)
{
if (isOn(option)) {
Debug d = new Debug();
d.prefix = prefix;
return d;
} else {
return null;
}
}
/**
* True if the system property "security.debug" contains the
* string "option".
*/
public static boolean isOn(String option)
{
if (args == null)
return false;
else {
if (args.indexOf("all") != -1)
return true;
else
return (args.indexOf(option) != -1);
}
}
/**
* Check if verbose messages is enabled for extra debugging.
*/
public static boolean isVerbose() {
return isOn("verbose");
}
/**
* print a message to stderr that is prefixed with the prefix
* created from the call to getInstance.
*/
public void println(String message)
{
System.err.println(prefix + ": "+message);
}
/**
* print a message to stderr that is prefixed with the prefix
* created from the call to getInstance and obj.
*/
public void println(Object obj, String message)
{
System.err.println(prefix + " [" + obj.getClass().getSimpleName() +
"@" + System.identityHashCode(obj) + "]: "+message);
}
/**
* print a blank line to stderr that is prefixed with the prefix.
*/
public void println()
{
System.err.println(prefix + ":");
}
/**
* print a message to stderr that is prefixed with the prefix.
*/
public static void println(String prefix, String message)
{
System.err.println(prefix + ": "+message);
}
/**
* PrintStream for debug methods. Currently only System.err is supported.
*/
public PrintStream getPrintStream() {
return System.err;
}
/**
* return a hexadecimal printed representation of the specified
* BigInteger object. the value is formatted to fit on lines of
* at least 75 characters, with embedded newlines. Words are
* separated for readability, with eight words (32 bytes) per line.
*/
public static String toHexString(BigInteger b) {
String hexValue = b.toString(16);
StringBuilder sb = new StringBuilder(hexValue.length()*2);
if (hexValue.startsWith("-")) {
sb.append(" -");
hexValue = hexValue.substring(1);
} else {
sb.append(" "); // four spaces
}
if ((hexValue.length()%2) != 0) {
// add back the leading 0
hexValue = "0" + hexValue;
}
int i=0;
while (i < hexValue.length()) {
// one byte at a time
sb.append(hexValue.substring(i, i + 2));
i+=2;
if (i!= hexValue.length()) {
if ((i%64) == 0) {
sb.append("\n "); // line after eight words
} else if (i%8 == 0) {
sb.append(" "); // space between words
}
}
}
return sb.toString();
}
/**
* change a string into lower case except permission classes and URLs.
*/
private static String marshal(String args) {
if (args != null) {
StringBuilder target = new StringBuilder();
StringBuffer source = new StringBuffer(args);
// obtain the "permission=<classname>" options
// the syntax of classname: IDENTIFIER.IDENTIFIER
// the regular express to match a class name:
// "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*"
String keyReg = "[Pp][Ee][Rr][Mm][Ii][Ss][Ss][Ii][Oo][Nn]=";
String keyStr = "permission=";
String reg = keyReg +
"[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*";
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(source);
StringBuffer left = new StringBuffer();
while (matcher.find()) {
String matched = matcher.group();
target.append(matched.replaceFirst(keyReg, keyStr));
target.append(" ");
// delete the matched sequence
matcher.appendReplacement(left, "");
}
matcher.appendTail(left);
source = left;
// obtain the "codebase=<URL>" options
// the syntax of URL is too flexible, and here assumes that the
// URL contains no space, comma(','), and semicolon(';'). That
// also means those characters also could be used as separator
// after codebase option.
// However, the assumption is incorrect in some special situation
// when the URL contains comma or semicolon
keyReg = "[Cc][Oo][Dd][Ee][Bb][Aa][Ss][Ee]=";
keyStr = "codebase=";
reg = keyReg + "[^, ;]*";
pattern = Pattern.compile(reg);
matcher = pattern.matcher(source);
left = new StringBuffer();
while (matcher.find()) {
String matched = matcher.group();
target.append(matched.replaceFirst(keyReg, keyStr));
target.append(" ");
// delete the matched sequence
matcher.appendReplacement(left, "");
}
matcher.appendTail(left);
source = left;
// convert the rest to lower-case characters
target.append(source.toString().toLowerCase(Locale.ENGLISH));
return target.toString();
}
return null;
}
private static final char[] hexDigits = "0123456789abcdef".toCharArray();
public static String toString(byte[] b) {
if (b == null) {
return "(null)";
}
StringBuilder sb = new StringBuilder(b.length * 3);
for (int i = 0; i < b.length; i++) {
int k = b[i] & 0xff;
if (i != 0) {
sb.append(':');
}
sb.append(hexDigits[k >>> 4]);
sb.append(hexDigits[k & 0xf]);
}
return sb.toString();
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 1997, 1999, 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.io.OutputStream;
/**
* Interface to an object that knows how to write its own DER
* encoding to an output stream.
*
* @author D. N. Hoover
*/
public interface DerEncoder {
/**
* DER encode this object and write the results to a stream.
*
* @param out the stream on which the DER encoding is written.
*/
public void derEncode(OutputStream out)
throws IOException;
}

View file

@ -0,0 +1,357 @@
/*
* Copyright (c) 1998, 2012, 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.util.ArrayList;
/**
* A package private utility class to convert indefinite length DER
* encoded byte arrays to definite length DER encoded byte arrays.
*
* This assumes that the basic data structure is "tag, length, value"
* triplet. In the case where the length is "indefinite", terminating
* end-of-contents bytes are expected.
*
* @author Hemma Prafullchandra
*/
class DerIndefLenConverter {
private static final int TAG_MASK = 0x1f; // bits 5-1
private static final int FORM_MASK = 0x20; // bits 6
private static final int CLASS_MASK = 0xC0; // bits 8 and 7
private static final int LEN_LONG = 0x80; // bit 8 set
private static final int LEN_MASK = 0x7f; // bits 7 - 1
private static final int SKIP_EOC_BYTES = 2;
private byte[] data, newData;
private int newDataPos, dataPos, dataSize, index;
private int unresolved = 0;
private ArrayList<Object> ndefsList = new ArrayList<Object>();
private int numOfTotalLenBytes = 0;
private boolean isEOC(int tag) {
return (((tag & TAG_MASK) == 0x00) && // EOC
((tag & FORM_MASK) == 0x00) && // primitive
((tag & CLASS_MASK) == 0x00)); // universal
}
// if bit 8 is set then it implies either indefinite length or long form
static boolean isLongForm(int lengthByte) {
return ((lengthByte & LEN_LONG) == LEN_LONG);
}
/*
* Default package private constructor
*/
DerIndefLenConverter() { }
/**
* Checks whether the given length byte is of the form
* <em>Indefinite</em>.
*
* @param lengthByte the length byte from a DER encoded
* object.
* @return true if the byte is of Indefinite form otherwise
* returns false.
*/
static boolean isIndefinite(int lengthByte) {
return (isLongForm(lengthByte) && ((lengthByte & LEN_MASK) == 0));
}
/**
* Parse the tag and if it is an end-of-contents tag then
* add the current position to the <code>eocList</code> vector.
*/
private void parseTag() throws IOException {
if (dataPos == dataSize)
return;
if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) {
int numOfEncapsulatedLenBytes = 0;
Object elem = null;
int index;
for (index = ndefsList.size()-1; index >= 0; index--) {
// Determine the first element in the vector that does not
// have a matching EOC
elem = ndefsList.get(index);
if (elem instanceof Integer) {
break;
} else {
numOfEncapsulatedLenBytes += ((byte[])elem).length - 3;
}
}
if (index < 0) {
throw new IOException("EOC does not have matching " +
"indefinite-length tag");
}
int sectionLen = dataPos - ((Integer)elem).intValue() +
numOfEncapsulatedLenBytes;
byte[] sectionLenBytes = getLengthBytes(sectionLen);
ndefsList.set(index, sectionLenBytes);
unresolved--;
// Add the number of bytes required to represent this section
// to the total number of length bytes,
// and subtract the indefinite-length tag (1 byte) and
// EOC bytes (2 bytes) for this section
numOfTotalLenBytes += (sectionLenBytes.length - 3);
}
dataPos++;
}
/**
* Write the tag and if it is an end-of-contents tag
* then skip the tag and its 1 byte length of zero.
*/
private void writeTag() {
if (dataPos == dataSize)
return;
int tag = data[dataPos++];
if (isEOC(tag) && (data[dataPos] == 0)) {
dataPos++; // skip length
writeTag();
} else
newData[newDataPos++] = (byte)tag;
}
/**
* Parse the length and if it is an indefinite length then add
* the current position to the <code>ndefsList</code> vector.
*/
private int parseLength() throws IOException {
int curLen = 0;
if (dataPos == dataSize)
return curLen;
int lenByte = data[dataPos++] & 0xff;
if (isIndefinite(lenByte)) {
ndefsList.add(dataPos);
unresolved++;
return curLen;
}
if (isLongForm(lenByte)) {
lenByte &= LEN_MASK;
if (lenByte > 4) {
throw new IOException("Too much data");
}
if ((dataSize - dataPos) < (lenByte + 1)) {
throw new IOException("Too little data");
}
for (int i = 0; i < lenByte; i++) {
curLen = (curLen << 8) + (data[dataPos++] & 0xff);
}
if (curLen < 0) {
throw new IOException("Invalid length bytes");
}
} else {
curLen = (lenByte & LEN_MASK);
}
return curLen;
}
/**
* Write the length and if it is an indefinite length
* then calculate the definite length from the positions
* of the indefinite length and its matching EOC terminator.
* Then, write the value.
*/
private void writeLengthAndValue() throws IOException {
if (dataPos == dataSize)
return;
int curLen = 0;
int lenByte = data[dataPos++] & 0xff;
if (isIndefinite(lenByte)) {
byte[] lenBytes = (byte[])ndefsList.get(index++);
System.arraycopy(lenBytes, 0, newData, newDataPos,
lenBytes.length);
newDataPos += lenBytes.length;
return;
}
if (isLongForm(lenByte)) {
lenByte &= LEN_MASK;
for (int i = 0; i < lenByte; i++) {
curLen = (curLen << 8) + (data[dataPos++] & 0xff);
}
if (curLen < 0) {
throw new IOException("Invalid length bytes");
}
} else {
curLen = (lenByte & LEN_MASK);
}
writeLength(curLen);
writeValue(curLen);
}
private void writeLength(int curLen) {
if (curLen < 128) {
newData[newDataPos++] = (byte)curLen;
} else if (curLen < (1 << 8)) {
newData[newDataPos++] = (byte)0x81;
newData[newDataPos++] = (byte)curLen;
} else if (curLen < (1 << 16)) {
newData[newDataPos++] = (byte)0x82;
newData[newDataPos++] = (byte)(curLen >> 8);
newData[newDataPos++] = (byte)curLen;
} else if (curLen < (1 << 24)) {
newData[newDataPos++] = (byte)0x83;
newData[newDataPos++] = (byte)(curLen >> 16);
newData[newDataPos++] = (byte)(curLen >> 8);
newData[newDataPos++] = (byte)curLen;
} else {
newData[newDataPos++] = (byte)0x84;
newData[newDataPos++] = (byte)(curLen >> 24);
newData[newDataPos++] = (byte)(curLen >> 16);
newData[newDataPos++] = (byte)(curLen >> 8);
newData[newDataPos++] = (byte)curLen;
}
}
private byte[] getLengthBytes(int curLen) {
byte[] lenBytes;
int index = 0;
if (curLen < 128) {
lenBytes = new byte[1];
lenBytes[index++] = (byte)curLen;
} else if (curLen < (1 << 8)) {
lenBytes = new byte[2];
lenBytes[index++] = (byte)0x81;
lenBytes[index++] = (byte)curLen;
} else if (curLen < (1 << 16)) {
lenBytes = new byte[3];
lenBytes[index++] = (byte)0x82;
lenBytes[index++] = (byte)(curLen >> 8);
lenBytes[index++] = (byte)curLen;
} else if (curLen < (1 << 24)) {
lenBytes = new byte[4];
lenBytes[index++] = (byte)0x83;
lenBytes[index++] = (byte)(curLen >> 16);
lenBytes[index++] = (byte)(curLen >> 8);
lenBytes[index++] = (byte)curLen;
} else {
lenBytes = new byte[5];
lenBytes[index++] = (byte)0x84;
lenBytes[index++] = (byte)(curLen >> 24);
lenBytes[index++] = (byte)(curLen >> 16);
lenBytes[index++] = (byte)(curLen >> 8);
lenBytes[index++] = (byte)curLen;
}
return lenBytes;
}
// Returns the number of bytes needed to represent the given length
// in ASN.1 notation
private int getNumOfLenBytes(int len) {
int numOfLenBytes = 0;
if (len < 128) {
numOfLenBytes = 1;
} else if (len < (1 << 8)) {
numOfLenBytes = 2;
} else if (len < (1 << 16)) {
numOfLenBytes = 3;
} else if (len < (1 << 24)) {
numOfLenBytes = 4;
} else {
numOfLenBytes = 5;
}
return numOfLenBytes;
}
/**
* Parse the value;
*/
private void parseValue(int curLen) {
dataPos += curLen;
}
/**
* Write the value;
*/
private void writeValue(int curLen) {
for (int i=0; i < curLen; i++)
newData[newDataPos++] = data[dataPos++];
}
/**
* Converts a indefinite length DER encoded byte array to
* a definte length DER encoding.
*
* @param indefData the byte array holding the indefinite
* length encoding.
* @return the byte array containing the definite length
* DER encoding.
* @exception IOException on parsing or re-writing errors.
*/
byte[] convert(byte[] indefData) throws IOException {
data = indefData;
dataPos=0; index=0;
dataSize = data.length;
int len=0;
int unused = 0;
// parse and set up the vectors of all the indefinite-lengths
while (dataPos < dataSize) {
parseTag();
len = parseLength();
parseValue(len);
if (unresolved == 0) {
unused = dataSize - dataPos;
dataSize = dataPos;
break;
}
}
if (unresolved != 0) {
throw new IOException("not all indef len BER resolved");
}
newData = new byte[dataSize + numOfTotalLenBytes + unused];
dataPos=0; newDataPos=0; index=0;
// write out the new byte array replacing all the indefinite-lengths
// and EOCs
while (dataPos < dataSize) {
writeTag();
writeLengthAndValue();
}
System.arraycopy(indefData, dataSize,
newData, dataSize + numOfTotalLenBytes, unused);
return newData;
}
}

View file

@ -0,0 +1,446 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Date;
import sun.util.calendar.CalendarDate;
import sun.util.calendar.CalendarSystem;
/**
* DER input buffer ... this is the main abstraction in the DER library
* which actively works with the "untyped byte stream" abstraction. It
* does so with impunity, since it's not intended to be exposed to
* anyone who could violate the "typed value stream" DER model and hence
* corrupt the input stream of DER values.
*
* @author David Brownell
*/
class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
boolean allowBER = true;
// used by sun/security/util/DerInputBuffer/DerInputBufferEqualsHashCode.java
DerInputBuffer(byte[] buf) {
this(buf, true);
}
DerInputBuffer(byte[] buf, boolean allowBER) {
super(buf);
this.allowBER = allowBER;
}
DerInputBuffer(byte[] buf, int offset, int len, boolean allowBER) {
super(buf, offset, len);
this.allowBER = allowBER;
}
DerInputBuffer dup() {
try {
DerInputBuffer retval = (DerInputBuffer)clone();
retval.mark(Integer.MAX_VALUE);
return retval;
} catch (CloneNotSupportedException e) {
throw new IllegalArgumentException(e.toString());
}
}
byte[] toByteArray() {
int len = available();
if (len <= 0)
return null;
byte[] retval = new byte[len];
System.arraycopy(buf, pos, retval, 0, len);
return retval;
}
int peek() throws IOException {
if (pos >= count)
throw new IOException("out of data");
else
return buf[pos];
}
/**
* Compares this DerInputBuffer for equality with the specified
* object.
*/
public boolean equals(Object other) {
if (other instanceof DerInputBuffer)
return equals((DerInputBuffer)other);
else
return false;
}
boolean equals(DerInputBuffer other) {
if (this == other)
return true;
int max = this.available();
if (other.available() != max)
return false;
for (int i = 0; i < max; i++) {
if (this.buf[this.pos + i] != other.buf[other.pos + i]) {
return false;
}
}
return true;
}
/**
* Returns a hashcode for this DerInputBuffer.
*
* @return a hashcode for this DerInputBuffer.
*/
public int hashCode() {
int retval = 0;
int len = available();
int p = pos;
for (int i = 0; i < len; i++)
retval += buf[p + i] * i;
return retval;
}
void truncate(int len) throws IOException {
if (len > available())
throw new IOException("insufficient data");
count = pos + len;
}
/**
* Returns the integer which takes up the specified number
* of bytes in this buffer as a BigInteger.
* @param len the number of bytes to use.
* @param makePositive whether to always return a positive value,
* irrespective of actual encoding
* @return the integer as a BigInteger.
*/
BigInteger getBigInteger(int len, boolean makePositive) throws IOException {
if (len > available())
throw new IOException("short read of integer");
if (len == 0) {
throw new IOException("Invalid encoding: zero length Int value");
}
byte[] bytes = new byte[len];
System.arraycopy(buf, pos, bytes, 0, len);
skip(len);
// BER allows leading 0s but DER does not
if (!allowBER && (len >= 2 && (bytes[0] == 0) && (bytes[1] >= 0))) {
throw new IOException("Invalid encoding: redundant leading 0s");
}
if (makePositive) {
return new BigInteger(1, bytes);
} else {
return new BigInteger(bytes);
}
}
/**
* Returns the integer which takes up the specified number
* of bytes in this buffer.
* @throws IOException if the result is not within the valid
* range for integer, i.e. between Integer.MIN_VALUE and
* Integer.MAX_VALUE.
* @param len the number of bytes to use.
* @return the integer.
*/
public int getInteger(int len) throws IOException {
BigInteger result = getBigInteger(len, false);
if (result.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0) {
throw new IOException("Integer below minimum valid value");
}
if (result.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
throw new IOException("Integer exceeds maximum valid value");
}
return result.intValue();
}
/**
* Returns the bit string which takes up the specified
* number of bytes in this buffer.
*/
public byte[] getBitString(int len) throws IOException {
if (len > available())
throw new IOException("short read of bit string");
if (len == 0) {
throw new IOException("Invalid encoding: zero length bit string");
}
int numOfPadBits = buf[pos];
if ((numOfPadBits < 0) || (numOfPadBits > 7)) {
throw new IOException("Invalid number of padding bits");
}
// minus the first byte which indicates the number of padding bits
byte[] retval = new byte[len - 1];
System.arraycopy(buf, pos + 1, retval, 0, len - 1);
if (numOfPadBits != 0) {
// get rid of the padding bits
retval[len - 2] &= (0xff << numOfPadBits);
}
skip(len);
return retval;
}
/**
* Returns the bit string which takes up the rest of this buffer.
*/
byte[] getBitString() throws IOException {
return getBitString(available());
}
/**
* Returns the bit string which takes up the rest of this buffer.
* The bit string need not be byte-aligned.
*/
BitArray getUnalignedBitString() throws IOException {
if (pos >= count)
return null;
/*
* Just copy the data into an aligned, padded octet buffer,
* and consume the rest of the buffer.
*/
int len = available();
int unusedBits = buf[pos] & 0xff;
if (unusedBits > 7 ) {
throw new IOException("Invalid value for unused bits: " + unusedBits);
}
byte[] bits = new byte[len - 1];
// number of valid bits
int length = (bits.length == 0) ? 0 : bits.length * 8 - unusedBits;
System.arraycopy(buf, pos + 1, bits, 0, len - 1);
BitArray bitArray = new BitArray(length, bits);
pos = count;
return bitArray;
}
/**
* Returns the UTC Time value that takes up the specified number
* of bytes in this buffer.
* @param len the number of bytes to use
*/
public Date getUTCTime(int len) throws IOException {
if (len > available())
throw new IOException("short read of DER UTC Time");
if (len < 11 || len > 17)
throw new IOException("DER UTC Time length error");
return getTime(len, false);
}
/**
* Returns the Generalized Time value that takes up the specified
* number of bytes in this buffer.
* @param len the number of bytes to use
*/
public Date getGeneralizedTime(int len) throws IOException {
if (len > available())
throw new IOException("short read of DER Generalized Time");
if (len < 13)
throw new IOException("DER Generalized Time length error");
return getTime(len, true);
}
/**
* Private helper routine to extract time from the der value.
* @param len the number of bytes to use
* @param generalized true if Generalized Time is to be read, false
* if UTC Time is to be read.
*/
private Date getTime(int len, boolean generalized) throws IOException {
/*
* UTC time encoded as ASCII chars:
* YYMMDDhhmmZ
* YYMMDDhhmmssZ
* YYMMDDhhmm+hhmm
* YYMMDDhhmm-hhmm
* YYMMDDhhmmss+hhmm
* YYMMDDhhmmss-hhmm
* UTC Time is broken in storing only two digits of year.
* If YY < 50, we assume 20YY;
* if YY >= 50, we assume 19YY, as per RFC 5280.
*
* Generalized time has a four-digit year and allows any
* precision specified in ISO 8601. However, for our purposes,
* we will only allow the same format as UTC time, except that
* fractional seconds (millisecond precision) are supported.
*/
int year, month, day, hour, minute, second, millis;
String type = null;
if (generalized) {
type = "Generalized";
year = 1000 * Character.digit((char)buf[pos++], 10);
year += 100 * Character.digit((char)buf[pos++], 10);
year += 10 * Character.digit((char)buf[pos++], 10);
year += Character.digit((char)buf[pos++], 10);
len -= 2; // For the two extra YY
} else {
type = "UTC";
year = 10 * Character.digit((char)buf[pos++], 10);
year += Character.digit((char)buf[pos++], 10);
if (year < 50) // origin 2000
year += 2000;
else
year += 1900; // origin 1900
}
month = 10 * Character.digit((char)buf[pos++], 10);
month += Character.digit((char)buf[pos++], 10);
day = 10 * Character.digit((char)buf[pos++], 10);
day += Character.digit((char)buf[pos++], 10);
hour = 10 * Character.digit((char)buf[pos++], 10);
hour += Character.digit((char)buf[pos++], 10);
minute = 10 * Character.digit((char)buf[pos++], 10);
minute += Character.digit((char)buf[pos++], 10);
len -= 10; // YYMMDDhhmm
/*
* We allow for non-encoded seconds, even though the
* IETF-PKIX specification says that the seconds should
* always be encoded even if it is zero.
*/
millis = 0;
if (len > 2) {
second = 10 * Character.digit((char)buf[pos++], 10);
second += Character.digit((char)buf[pos++], 10);
len -= 2;
// handle fractional seconds (if present)
if (buf[pos] == '.' || buf[pos] == ',') {
len --;
pos++;
int precision = 0;
while (buf[pos] != 'Z' &&
buf[pos] != '+' &&
buf[pos] != '-') {
// Validate all digits in the fractional part but
// store millisecond precision only
int thisDigit = Character.digit((char)buf[pos], 10);
precision++;
pos++;
switch (precision) {
case 1:
millis += 100 * thisDigit;
break;
case 2:
millis += 10 * thisDigit;
break;
case 3:
millis += thisDigit;
break;
}
}
if (precision == 0) {
throw new IOException("Parse " + type +
" time, empty fractional part");
}
len -= precision;
}
} else
second = 0;
if (month == 0 || day == 0
|| month > 12 || day > 31
|| hour >= 24 || minute >= 60 || second >= 60)
throw new IOException("Parse " + type + " time, invalid format");
/*
* Generalized time can theoretically allow any precision,
* but we're not supporting that.
*/
CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
CalendarDate date = gcal.newCalendarDate(null); // no time zone
date.setDate(year, month, day);
date.setTimeOfDay(hour, minute, second, millis);
long time = gcal.getTime(date);
/*
* Finally, "Z" or "+hhmm" or "-hhmm" ... offsets change hhmm
*/
if (! (len == 1 || len == 5))
throw new IOException("Parse " + type + " time, invalid offset");
int hr, min;
switch (buf[pos++]) {
case '+':
hr = 10 * Character.digit((char)buf[pos++], 10);
hr += Character.digit((char)buf[pos++], 10);
min = 10 * Character.digit((char)buf[pos++], 10);
min += Character.digit((char)buf[pos++], 10);
if (hr >= 24 || min >= 60)
throw new IOException("Parse " + type + " time, +hhmm");
time -= ((hr * 60) + min) * 60 * 1000;
break;
case '-':
hr = 10 * Character.digit((char)buf[pos++], 10);
hr += Character.digit((char)buf[pos++], 10);
min = 10 * Character.digit((char)buf[pos++], 10);
min += Character.digit((char)buf[pos++], 10);
if (hr >= 24 || min >= 60)
throw new IOException("Parse " + type + " time, -hhmm");
time += ((hr * 60) + min) * 60 * 1000;
break;
case 'Z':
break;
default:
throw new IOException("Parse " + type + " time, garbage offset");
}
return new Date(time);
}
}

View file

@ -0,0 +1,666 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.InputStream;
import java.io.IOException;
import java.io.EOFException;
import java.util.Date;
import java.util.Vector;
import java.math.BigInteger;
import java.io.DataInputStream;
/**
* A DER input stream, used for parsing ASN.1 DER-encoded data such as
* that found in X.509 certificates. DER is a subset of BER/1, which has
* the advantage that it allows only a single encoding of primitive data.
* (High level data such as dates still support many encodings.) That is,
* it uses the "Definite" Encoding Rules (DER) not the "Basic" ones (BER).
*
* <P>Note that, like BER/1, DER streams are streams of explicitly
* tagged data values. Accordingly, this programming interface does
* not expose any variant of the java.io.InputStream interface, since
* that kind of input stream holds untagged data values and using that
* I/O model could prevent correct parsing of the DER data.
*
* <P>At this time, this class supports only a subset of the types of DER
* data encodings which are defined. That subset is sufficient for parsing
* most X.509 certificates.
*
*
* @author David Brownell
* @author Amit Kapoor
* @author Hemma Prafullchandra
*/
public class DerInputStream {
/*
* This version only supports fully buffered DER. This is easy to
* work with, though if large objects are manipulated DER becomes
* awkward to deal with. That's where BER is useful, since BER
* handles streaming data relatively well.
*/
DerInputBuffer buffer;
/** The DER tag of the value; one of the tag_ constants. */
public byte tag;
/**
* Create a DER input stream from a data buffer. The buffer is not
* copied, it is shared. Accordingly, the buffer should be treated
* as read-only.
*
* @param data the buffer from which to create the string (CONSUMED)
*/
public DerInputStream(byte[] data) throws IOException {
init(data, 0, data.length, true);
}
/**
* Create a DER input stream from part of a data buffer with
* additional arg to control whether DER checks are enforced.
* The buffer is not copied, it is shared. Accordingly, the
* buffer should be treated as read-only.
*
* @param data the buffer from which to create the string (CONSUMED)
* @param offset the first index of <em>data</em> which will
* be read as DER input in the new stream
* @param len how long a chunk of the buffer to use,
* starting at "offset"
* @param allowBER whether to allow constructed indefinite-length
* encoding as well as tolerate leading 0s
*/
public DerInputStream(byte[] data, int offset, int len,
boolean allowBER) throws IOException {
init(data, offset, len, allowBER);
}
/**
* Create a DER input stream from part of a data buffer.
* The buffer is not copied, it is shared. Accordingly, the
* buffer should be treated as read-only.
*
* @param data the buffer from which to create the string (CONSUMED)
* @param offset the first index of <em>data</em> which will
* be read as DER input in the new stream
* @param len how long a chunk of the buffer to use,
* starting at "offset"
*/
public DerInputStream(byte[] data, int offset, int len) throws IOException {
init(data, offset, len, true);
}
/*
* private helper routine
*/
private void init(byte[] data, int offset, int len, boolean allowBER) throws IOException {
if ((offset+2 > data.length) || (offset+len > data.length)) {
throw new IOException("Encoding bytes too short");
}
// check for indefinite length encoding
if (DerIndefLenConverter.isIndefinite(data[offset+1])) {
if (!allowBER) {
throw new IOException("Indefinite length BER encoding found");
} else {
byte[] inData = new byte[len];
System.arraycopy(data, offset, inData, 0, len);
DerIndefLenConverter derIn = new DerIndefLenConverter();
buffer = new DerInputBuffer(derIn.convert(inData), allowBER);
}
} else {
buffer = new DerInputBuffer(data, offset, len, allowBER);
}
buffer.mark(Integer.MAX_VALUE);
}
DerInputStream(DerInputBuffer buf) {
buffer = buf;
buffer.mark(Integer.MAX_VALUE);
}
/**
* Creates a new DER input stream from part of this input stream.
*
* @param len how long a chunk of the current input stream to use,
* starting at the current position.
* @param do_skip true if the existing data in the input stream should
* be skipped. If this value is false, the next data read
* on this stream and the newly created stream will be the
* same.
*/
public DerInputStream subStream(int len, boolean do_skip)
throws IOException {
DerInputBuffer newbuf = buffer.dup();
newbuf.truncate(len);
if (do_skip) {
buffer.skip(len);
}
return new DerInputStream(newbuf);
}
/**
* Return what has been written to this DerInputStream
* as a byte array. Useful for debugging.
*/
public byte[] toByteArray() {
return buffer.toByteArray();
}
/*
* PRIMITIVES -- these are "universal" ASN.1 simple types.
*
* INTEGER, ENUMERATED, BIT STRING, OCTET STRING, NULL
* OBJECT IDENTIFIER, SEQUENCE (OF), SET (OF)
* UTF8String, PrintableString, T61String, IA5String, UTCTime,
* GeneralizedTime, BMPString.
* Note: UniversalString not supported till encoder is available.
*/
/**
* Get an integer from the input stream as an integer.
*
* @return the integer held in this DER input stream.
*/
public int getInteger() throws IOException {
if (buffer.read() != DerValue.tag_Integer) {
throw new IOException("DER input, Integer tag error");
}
return buffer.getInteger(getDefiniteLength(buffer));
}
/**
* Get a integer from the input stream as a BigInteger object.
*
* @return the integer held in this DER input stream.
*/
public BigInteger getBigInteger() throws IOException {
if (buffer.read() != DerValue.tag_Integer) {
throw new IOException("DER input, Integer tag error");
}
return buffer.getBigInteger(getDefiniteLength(buffer), false);
}
/**
* Returns an ASN.1 INTEGER value as a positive BigInteger.
* This is just to deal with implementations that incorrectly encode
* some values as negative.
*
* @return the integer held in this DER value as a BigInteger.
*/
public BigInteger getPositiveBigInteger() throws IOException {
if (buffer.read() != DerValue.tag_Integer) {
throw new IOException("DER input, Integer tag error");
}
return buffer.getBigInteger(getDefiniteLength(buffer), true);
}
/**
* Get an enumerated from the input stream.
*
* @return the integer held in this DER input stream.
*/
public int getEnumerated() throws IOException {
if (buffer.read() != DerValue.tag_Enumerated) {
throw new IOException("DER input, Enumerated tag error");
}
return buffer.getInteger(getDefiniteLength(buffer));
}
/**
* Get a bit string from the input stream. Padded bits (if any)
* will be stripped off before the bit string is returned.
*/
public byte[] getBitString() throws IOException {
if (buffer.read() != DerValue.tag_BitString)
throw new IOException("DER input not an bit string");
return buffer.getBitString(getDefiniteLength(buffer));
}
/**
* Get a bit string from the input stream. The bit string need
* not be byte-aligned.
*/
public BitArray getUnalignedBitString() throws IOException {
if (buffer.read() != DerValue.tag_BitString) {
throw new IOException("DER input not a bit string");
}
int length = getDefiniteLength(buffer);
if (length == 0) {
return new BitArray(0);
}
/*
* First byte = number of excess bits in the last octet of the
* representation.
*/
length--;
int excessBits = buffer.read();
if (excessBits < 0) {
throw new IOException("Unused bits of bit string invalid");
}
int validBits = length*8 - excessBits;
if (validBits < 0) {
throw new IOException("Valid bits of bit string invalid");
}
byte[] repn = new byte[length];
if ((length != 0) && (buffer.read(repn) != length)) {
throw new IOException("Short read of DER bit string");
}
return new BitArray(validBits, repn);
}
/**
* Returns an ASN.1 OCTET STRING from the input stream.
*/
public byte[] getOctetString() throws IOException {
if (buffer.read() != DerValue.tag_OctetString)
throw new IOException("DER input not an octet string");
int length = getDefiniteLength(buffer);
byte[] retval = new byte[length];
if ((length != 0) && (buffer.read(retval) != length))
throw new IOException("Short read of DER octet string");
return retval;
}
/**
* Returns the asked number of bytes from the input stream.
*/
public void getBytes(byte[] val) throws IOException {
if ((val.length != 0) && (buffer.read(val) != val.length)) {
throw new IOException("Short read of DER octet string");
}
}
/**
* Reads an encoded null value from the input stream.
*/
public void getNull() throws IOException {
if (buffer.read() != DerValue.tag_Null || buffer.read() != 0)
throw new IOException("getNull, bad data");
}
/**
* Reads an X.200 style Object Identifier from the stream.
*/
public ObjectIdentifier getOID() throws IOException {
return new ObjectIdentifier(this);
}
/**
* Return a sequence of encoded entities. ASN.1 sequences are
* ordered, and they are often used, like a "struct" in C or C++,
* to group data values. They may have optional or context
* specific values.
*
* @param startLen guess about how long the sequence will be
* (used to initialize an auto-growing data structure)
* @return array of the values in the sequence
*/
public DerValue[] getSequence(int startLen) throws IOException {
tag = (byte)buffer.read();
if (tag != DerValue.tag_Sequence)
throw new IOException("Sequence tag error");
return readVector(startLen);
}
/**
* Return a set of encoded entities. ASN.1 sets are unordered,
* though DER may specify an order for some kinds of sets (such
* as the attributes in an X.500 relative distinguished name)
* to facilitate binary comparisons of encoded values.
*
* @param startLen guess about how large the set will be
* (used to initialize an auto-growing data structure)
* @return array of the values in the sequence
*/
public DerValue[] getSet(int startLen) throws IOException {
tag = (byte)buffer.read();
if (tag != DerValue.tag_Set)
throw new IOException("Set tag error");
return readVector(startLen);
}
/**
* Return a set of encoded entities. ASN.1 sets are unordered,
* though DER may specify an order for some kinds of sets (such
* as the attributes in an X.500 relative distinguished name)
* to facilitate binary comparisons of encoded values.
*
* @param startLen guess about how large the set will be
* (used to initialize an auto-growing data structure)
* @param implicit if true tag is assumed implicit.
* @return array of the values in the sequence
*/
public DerValue[] getSet(int startLen, boolean implicit)
throws IOException {
tag = (byte)buffer.read();
if (!implicit) {
if (tag != DerValue.tag_Set) {
throw new IOException("Set tag error");
}
}
return (readVector(startLen));
}
/*
* Read a "vector" of values ... set or sequence have the
* same encoding, except for the initial tag, so both use
* this same helper routine.
*/
protected DerValue[] readVector(int startLen) throws IOException {
DerInputStream newstr;
byte lenByte = (byte)buffer.read();
int len = getLength(lenByte, buffer);
if (len == -1) {
// indefinite length encoding found
int readLen = buffer.available();
int offset = 2; // for tag and length bytes
byte[] indefData = new byte[readLen + offset];
indefData[0] = tag;
indefData[1] = lenByte;
DataInputStream dis = new DataInputStream(buffer);
dis.readFully(indefData, offset, readLen);
dis.close();
DerIndefLenConverter derIn = new DerIndefLenConverter();
buffer = new DerInputBuffer(derIn.convert(indefData), buffer.allowBER);
if (tag != buffer.read())
throw new IOException("Indefinite length encoding" +
" not supported");
len = DerInputStream.getDefiniteLength(buffer);
}
if (len == 0)
// return empty array instead of null, which should be
// used only for missing optionals
return new DerValue[0];
/*
* Create a temporary stream from which to read the data,
* unless it's not really needed.
*/
if (buffer.available() == len)
newstr = this;
else
newstr = subStream(len, true);
/*
* Pull values out of the stream.
*/
Vector<DerValue> vec = new Vector<>(startLen);
DerValue value;
do {
value = new DerValue(newstr.buffer, buffer.allowBER);
vec.addElement(value);
} while (newstr.available() > 0);
if (newstr.available() != 0)
throw new IOException("Extra data at end of vector");
/*
* Now stick them into the array we're returning.
*/
int i, max = vec.size();
DerValue[] retval = new DerValue[max];
for (i = 0; i < max; i++)
retval[i] = vec.elementAt(i);
return retval;
}
/**
* Get a single DER-encoded value from the input stream.
* It can often be useful to pull a value from the stream
* and defer parsing it. For example, you can pull a nested
* sequence out with one call, and only examine its elements
* later when you really need to.
*/
public DerValue getDerValue() throws IOException {
return new DerValue(buffer);
}
/**
* Read a string that was encoded as a UTF8String DER value.
*/
public String getUTF8String() throws IOException {
return readString(DerValue.tag_UTF8String, "UTF-8", "UTF8");
}
/**
* Read a string that was encoded as a PrintableString DER value.
*/
public String getPrintableString() throws IOException {
return readString(DerValue.tag_PrintableString, "Printable",
"ASCII");
}
/**
* Read a string that was encoded as a T61String DER value.
*/
public String getT61String() throws IOException {
/*
* Works for common characters between T61 and ASCII.
*/
return readString(DerValue.tag_T61String, "T61", "ISO-8859-1");
}
/**
* Read a string that was encoded as a IA5tring DER value.
*/
public String getIA5String() throws IOException {
return readString(DerValue.tag_IA5String, "IA5", "ASCII");
}
/**
* Read a string that was encoded as a BMPString DER value.
*/
public String getBMPString() throws IOException {
return readString(DerValue.tag_BMPString, "BMP",
"UnicodeBigUnmarked");
}
/**
* Read a string that was encoded as a GeneralString DER value.
*/
public String getGeneralString() throws IOException {
return readString(DerValue.tag_GeneralString, "General",
"ASCII");
}
/**
* Private helper routine to read an encoded string from the input
* stream.
* @param stringTag the tag for the type of string to read
* @param stringName a name to display in error messages
* @param enc the encoder to use to interpret the data. Should
* correspond to the stringTag above.
*/
private String readString(byte stringTag, String stringName,
String enc) throws IOException {
if (buffer.read() != stringTag)
throw new IOException("DER input not a " +
stringName + " string");
int length = getDefiniteLength(buffer);
byte[] retval = new byte[length];
if ((length != 0) && (buffer.read(retval) != length))
throw new IOException("Short read of DER " +
stringName + " string");
return new String(retval, enc);
}
/**
* Get a UTC encoded time value from the input stream.
*/
public Date getUTCTime() throws IOException {
if (buffer.read() != DerValue.tag_UtcTime)
throw new IOException("DER input, UTCtime tag invalid ");
return buffer.getUTCTime(getDefiniteLength(buffer));
}
/**
* Get a Generalized encoded time value from the input stream.
*/
public Date getGeneralizedTime() throws IOException {
if (buffer.read() != DerValue.tag_GeneralizedTime)
throw new IOException("DER input, GeneralizedTime tag invalid ");
return buffer.getGeneralizedTime(getDefiniteLength(buffer));
}
/*
* Get a byte from the input stream.
*/
// package private
int getByte() throws IOException {
return (0x00ff & buffer.read());
}
public int peekByte() throws IOException {
return buffer.peek();
}
// package private
int getLength() throws IOException {
return getLength(buffer);
}
/*
* Get a length from the input stream, allowing for at most 32 bits of
* encoding to be used. (Not the same as getting a tagged integer!)
*
* @return the length or -1 if indefinite length found.
* @exception IOException on parsing error or unsupported lengths.
*/
static int getLength(InputStream in) throws IOException {
return getLength(in.read(), in);
}
/*
* Get a length from the input stream, allowing for at most 32 bits of
* encoding to be used. (Not the same as getting a tagged integer!)
*
* @return the length or -1 if indefinite length found.
* @exception IOException on parsing error or unsupported lengths.
*/
static int getLength(int lenByte, InputStream in) throws IOException {
int value, tmp;
if (lenByte == -1) {
throw new IOException("Short read of DER length");
}
String mdName = "DerInputStream.getLength(): ";
tmp = lenByte;
if ((tmp & 0x080) == 0x00) { // short form, 1 byte datum
value = tmp;
} else { // long form or indefinite
tmp &= 0x07f;
/*
* NOTE: tmp == 0 indicates indefinite length encoded data.
* tmp > 4 indicates more than 4Gb of data.
*/
if (tmp == 0)
return -1;
if (tmp < 0 || tmp > 4)
throw new IOException(mdName + "lengthTag=" + tmp + ", "
+ ((tmp < 0) ? "incorrect DER encoding." : "too big."));
value = 0x0ff & in.read();
tmp--;
if (value == 0) {
// DER requires length value be encoded in minimum number of bytes
throw new IOException(mdName + "Redundant length bytes found");
}
while (tmp-- > 0) {
value <<= 8;
value += 0x0ff & in.read();
}
if (value < 0) {
throw new IOException(mdName + "Invalid length bytes");
} else if (value <= 127) {
throw new IOException(mdName + "Should use short form for length");
}
}
return value;
}
int getDefiniteLength() throws IOException {
return getDefiniteLength(buffer);
}
/*
* Get a length from the input stream.
*
* @return the length
* @exception IOException on parsing error or if indefinite length found.
*/
static int getDefiniteLength(InputStream in) throws IOException {
int len = getLength(in);
if (len < 0) {
throw new IOException("Indefinite length encoding not supported");
}
return len;
}
/**
* Mark the current position in the buffer, so that
* a later call to <code>reset</code> will return here.
*/
public void mark(int value) { buffer.mark(value); }
/**
* Return to the position of the last <code>mark</code>
* call. A mark is implicitly set at the beginning of
* the stream when it is created.
*/
public void reset() { buffer.reset(); }
/**
* Returns the number of bytes available for reading.
* This is most useful for testing whether the stream is
* empty.
*/
public int available() { return buffer.available(); }
}

View file

@ -0,0 +1,576 @@
/*
* Copyright (c) 1996, 2010, 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.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.Comparator;
import java.util.Arrays;
import java.math.BigInteger;
import java.util.Locale;
/**
* Output stream marshaling DER-encoded data. This is eventually provided
* in the form of a byte array; there is no advance limit on the size of
* that byte array.
*
* <P>At this time, this class supports only a subset of the types of
* DER data encodings which are defined. That subset is sufficient for
* generating most X.509 certificates.
*
*
* @author David Brownell
* @author Amit Kapoor
* @author Hemma Prafullchandra
*/
public class DerOutputStream
extends ByteArrayOutputStream implements DerEncoder {
/**
* Construct an DER output stream.
*
* @param size how large a buffer to preallocate.
*/
public DerOutputStream(int size) { super(size); }
/**
* Construct an DER output stream.
*/
public DerOutputStream() { }
/**
* Writes tagged, pre-marshaled data. This calcuates and encodes
* the length, so that the output data is the standard triple of
* { tag, length, data } used by all DER values.
*
* @param tag the DER value tag for the data, such as
* <em>DerValue.tag_Sequence</em>
* @param buf buffered data, which must be DER-encoded
*/
public void write(byte tag, byte[] buf) throws IOException {
write(tag);
putLength(buf.length);
write(buf, 0, buf.length);
}
/**
* Writes tagged data using buffer-to-buffer copy. As above,
* this writes a standard DER record. This is often used when
* efficiently encapsulating values in sequences.
*
* @param tag the DER value tag for the data, such as
* <em>DerValue.tag_Sequence</em>
* @param out buffered data
*/
public void write(byte tag, DerOutputStream out) throws IOException {
write(tag);
putLength(out.count);
write(out.buf, 0, out.count);
}
/**
* Writes implicitly tagged data using buffer-to-buffer copy. As above,
* this writes a standard DER record. This is often used when
* efficiently encapsulating implicitly tagged values.
*
* @param tag the DER value of the context-specific tag that replaces
* original tag of the value in the output, such as in
* <pre>
* <em> {@code <field> [N] IMPLICIT <type>}</em>
* </pre>
* For example, <em>FooLength [1] IMPLICIT INTEGER</em>, with value=4;
* would be encoded as "81 01 04" whereas in explicit
* tagging it would be encoded as "A1 03 02 01 04".
* Notice that the tag is A1 and not 81, this is because with
* explicit tagging the form is always constructed.
* @param value original value being implicitly tagged
*/
public void writeImplicit(byte tag, DerOutputStream value)
throws IOException {
write(tag);
write(value.buf, 1, value.count-1);
}
/**
* Marshals pre-encoded DER value onto the output stream.
*/
public void putDerValue(DerValue val) throws IOException {
val.encode(this);
}
/*
* PRIMITIVES -- these are "universal" ASN.1 simple types.
*
* BOOLEAN, INTEGER, BIT STRING, OCTET STRING, NULL
* OBJECT IDENTIFIER, SEQUENCE(OF), SET(OF)
* PrintableString, T61String, IA5String, UTCTime
*/
/**
* Marshals a DER boolean on the output stream.
*/
public void putBoolean(boolean val) throws IOException {
write(DerValue.tag_Boolean);
putLength(1);
if (val) {
write(0xff);
} else {
write(0);
}
}
/**
* Marshals a DER enumerated on the output stream.
* @param i the enumerated value.
*/
public void putEnumerated(int i) throws IOException {
write(DerValue.tag_Enumerated);
putIntegerContents(i);
}
/**
* Marshals a DER integer on the output stream.
*
* @param i the integer in the form of a BigInteger.
*/
public void putInteger(BigInteger i) throws IOException {
write(DerValue.tag_Integer);
byte[] buf = i.toByteArray(); // least number of bytes
putLength(buf.length);
write(buf, 0, buf.length);
}
/**
* Marshals a DER integer on the output stream.
* @param i the integer in the form of an Integer.
*/
public void putInteger(Integer i) throws IOException {
putInteger(i.intValue());
}
/**
* Marshals a DER integer on the output stream.
* @param i the integer.
*/
public void putInteger(int i) throws IOException {
write(DerValue.tag_Integer);
putIntegerContents(i);
}
private void putIntegerContents(int i) throws IOException {
byte[] bytes = new byte[4];
int start = 0;
// Obtain the four bytes of the int
bytes[3] = (byte) (i & 0xff);
bytes[2] = (byte)((i & 0xff00) >>> 8);
bytes[1] = (byte)((i & 0xff0000) >>> 16);
bytes[0] = (byte)((i & 0xff000000) >>> 24);
// Reduce them to the least number of bytes needed to
// represent this int
if (bytes[0] == (byte)0xff) {
// Eliminate redundant 0xff
for (int j = 0; j < 3; j++) {
if ((bytes[j] == (byte)0xff) &&
((bytes[j+1] & 0x80) == 0x80))
start++;
else
break;
}
} else if (bytes[0] == 0x00) {
// Eliminate redundant 0x00
for (int j = 0; j < 3; j++) {
if ((bytes[j] == 0x00) &&
((bytes[j+1] & 0x80) == 0))
start++;
else
break;
}
}
putLength(4 - start);
for (int k = start; k < 4; k++)
write(bytes[k]);
}
/**
* Marshals a DER bit string on the output stream. The bit
* string must be byte-aligned.
*
* @param bits the bit string, MSB first
*/
public void putBitString(byte[] bits) throws IOException {
write(DerValue.tag_BitString);
putLength(bits.length + 1);
write(0); // all of last octet is used
write(bits);
}
/**
* Marshals a DER bit string on the output stream.
* The bit strings need not be byte-aligned.
*
* @param ba the bit string, MSB first
*/
public void putUnalignedBitString(BitArray ba) throws IOException {
byte[] bits = ba.toByteArray();
write(DerValue.tag_BitString);
putLength(bits.length + 1);
write(bits.length*8 - ba.length()); // excess bits in last octet
write(bits);
}
/**
* Marshals a truncated DER bit string on the output stream.
* The bit strings need not be byte-aligned.
*
* @param ba the bit string, MSB first
*/
public void putTruncatedUnalignedBitString(BitArray ba) throws IOException {
putUnalignedBitString(ba.truncate());
}
/**
* DER-encodes an ASN.1 OCTET STRING value on the output stream.
*
* @param octets the octet string
*/
public void putOctetString(byte[] octets) throws IOException {
write(DerValue.tag_OctetString, octets);
}
/**
* Marshals a DER "null" value on the output stream. These are
* often used to indicate optional values which have been omitted.
*/
public void putNull() throws IOException {
write(DerValue.tag_Null);
putLength(0);
}
/**
* Marshals an object identifier (OID) on the output stream.
* Corresponds to the ASN.1 "OBJECT IDENTIFIER" construct.
*/
public void putOID(ObjectIdentifier oid) throws IOException {
oid.encode(this);
}
/**
* Marshals a sequence on the output stream. This supports both
* the ASN.1 "SEQUENCE" (zero to N values) and "SEQUENCE OF"
* (one to N values) constructs.
*/
public void putSequence(DerValue[] seq) throws IOException {
DerOutputStream bytes = new DerOutputStream();
int i;
for (i = 0; i < seq.length; i++)
seq[i].encode(bytes);
write(DerValue.tag_Sequence, bytes);
}
/**
* Marshals the contents of a set on the output stream without
* ordering the elements. Ok for BER encoding, but not for DER
* encoding.
*
* For DER encoding, use orderedPutSet() or orderedPutSetOf().
*/
public void putSet(DerValue[] set) throws IOException {
DerOutputStream bytes = new DerOutputStream();
int i;
for (i = 0; i < set.length; i++)
set[i].encode(bytes);
write(DerValue.tag_Set, bytes);
}
/**
* Marshals the contents of a set on the output stream. Sets
* are semantically unordered, but DER requires that encodings of
* set elements be sorted into ascending lexicographical order
* before being output. Hence sets with the same tags and
* elements have the same DER encoding.
*
* This method supports the ASN.1 "SET OF" construct, but not
* "SET", which uses a different order.
*/
public void putOrderedSetOf(byte tag, DerEncoder[] set) throws IOException {
putOrderedSet(tag, set, lexOrder);
}
/**
* Marshals the contents of a set on the output stream. Sets
* are semantically unordered, but DER requires that encodings of
* set elements be sorted into ascending tag order
* before being output. Hence sets with the same tags and
* elements have the same DER encoding.
*
* This method supports the ASN.1 "SET" construct, but not
* "SET OF", which uses a different order.
*/
public void putOrderedSet(byte tag, DerEncoder[] set) throws IOException {
putOrderedSet(tag, set, tagOrder);
}
/**
* Lexicographical order comparison on byte arrays, for ordering
* elements of a SET OF objects in DER encoding.
*/
private static ByteArrayLexOrder lexOrder = new ByteArrayLexOrder();
/**
* Tag order comparison on byte arrays, for ordering elements of
* SET objects in DER encoding.
*/
private static ByteArrayTagOrder tagOrder = new ByteArrayTagOrder();
/**
* Marshals a the contents of a set on the output stream with the
* encodings of its sorted in increasing order.
*
* @param order the order to use when sorting encodings of components.
*/
private void putOrderedSet(byte tag, DerEncoder[] set,
Comparator<byte[]> order) throws IOException {
DerOutputStream[] streams = new DerOutputStream[set.length];
for (int i = 0; i < set.length; i++) {
streams[i] = new DerOutputStream();
set[i].derEncode(streams[i]);
}
// order the element encodings
byte[][] bufs = new byte[streams.length][];
for (int i = 0; i < streams.length; i++) {
bufs[i] = streams[i].toByteArray();
}
Arrays.<byte[]>sort(bufs, order);
DerOutputStream bytes = new DerOutputStream();
for (int i = 0; i < streams.length; i++) {
bytes.write(bufs[i]);
}
write(tag, bytes);
}
/**
* Marshals a string as a DER encoded UTF8String.
*/
public void putUTF8String(String s) throws IOException {
writeString(s, DerValue.tag_UTF8String, "UTF8");
}
/**
* Marshals a string as a DER encoded PrintableString.
*/
public void putPrintableString(String s) throws IOException {
writeString(s, DerValue.tag_PrintableString, "ASCII");
}
/**
* Marshals a string as a DER encoded T61String.
*/
public void putT61String(String s) throws IOException {
/*
* Works for characters that are defined in both ASCII and
* T61.
*/
writeString(s, DerValue.tag_T61String, "ISO-8859-1");
}
/**
* Marshals a string as a DER encoded IA5String.
*/
public void putIA5String(String s) throws IOException {
writeString(s, DerValue.tag_IA5String, "ASCII");
}
/**
* Marshals a string as a DER encoded BMPString.
*/
public void putBMPString(String s) throws IOException {
writeString(s, DerValue.tag_BMPString, "UnicodeBigUnmarked");
}
/**
* Marshals a string as a DER encoded GeneralString.
*/
public void putGeneralString(String s) throws IOException {
writeString(s, DerValue.tag_GeneralString, "ASCII");
}
/**
* Private helper routine for writing DER encoded string values.
* @param s the string to write
* @param stringTag one of the DER string tags that indicate which
* encoding should be used to write the string out.
* @param enc the name of the encoder that should be used corresponding
* to the above tag.
*/
private void writeString(String s, byte stringTag, String enc)
throws IOException {
byte[] data = s.getBytes(enc);
write(stringTag);
putLength(data.length);
write(data);
}
/**
* Marshals a DER UTC time/date value.
*
* <P>YYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time
* and with seconds (even if seconds=0) as per RFC 5280.
*/
public void putUTCTime(Date d) throws IOException {
putTime(d, DerValue.tag_UtcTime);
}
/**
* Marshals a DER Generalized Time/date value.
*
* <P>YYYYMMDDhhmmss{Z|+hhmm|-hhmm} ... emits only using Zulu time
* and with seconds (even if seconds=0) as per RFC 5280.
*/
public void putGeneralizedTime(Date d) throws IOException {
putTime(d, DerValue.tag_GeneralizedTime);
}
/**
* Private helper routine for marshalling a DER UTC/Generalized
* time/date value. If the tag specified is not that for UTC Time
* then it defaults to Generalized Time.
* @param d the date to be marshalled
* @param tag the tag for UTC Time or Generalized Time
*/
private void putTime(Date d, byte tag) throws IOException {
/*
* Format the date.
*/
TimeZone tz = TimeZone.getTimeZone("GMT");
String pattern = null;
if (tag == DerValue.tag_UtcTime) {
pattern = "yyMMddHHmmss'Z'";
} else {
tag = DerValue.tag_GeneralizedTime;
pattern = "yyyyMMddHHmmss'Z'";
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.US);
sdf.setTimeZone(tz);
byte[] time = (sdf.format(d)).getBytes("ISO-8859-1");
/*
* Write the formatted date.
*/
write(tag);
putLength(time.length);
write(time);
}
/**
* Put the encoding of the length in the stream.
*
* @param len the length of the attribute.
* @exception IOException on writing errors.
*/
public void putLength(int len) throws IOException {
if (len < 128) {
write((byte)len);
} else if (len < (1 << 8)) {
write((byte)0x081);
write((byte)len);
} else if (len < (1 << 16)) {
write((byte)0x082);
write((byte)(len >> 8));
write((byte)len);
} else if (len < (1 << 24)) {
write((byte)0x083);
write((byte)(len >> 16));
write((byte)(len >> 8));
write((byte)len);
} else {
write((byte)0x084);
write((byte)(len >> 24));
write((byte)(len >> 16));
write((byte)(len >> 8));
write((byte)len);
}
}
/**
* Put the tag of the attribute in the stream.
*
* @param tagClass the tag class type, one of UNIVERSAL, CONTEXT,
* APPLICATION or PRIVATE
* @param form if true, the value is constructed, otherwise it is
* primitive.
* @param val the tag value
*/
public void putTag(byte tagClass, boolean form, byte val) {
byte tag = (byte)(tagClass | val);
if (form) {
tag |= (byte)0x20;
}
write(tag);
}
/**
* Write the current contents of this <code>DerOutputStream</code>
* to an <code>OutputStream</code>.
*
* @exception IOException on output error.
*/
public void derEncode(OutputStream out) throws IOException {
out.write(toByteArray());
}
}

View file

@ -0,0 +1,954 @@
/**
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.*;
import java.math.BigInteger;
import java.util.Date;
/**
* Represents a single DER-encoded value. DER encoding rules are a subset
* of the "Basic" Encoding Rules (BER), but they only support a single way
* ("Definite" encoding) to encode any given value.
*
* <P>All DER-encoded data are triples <em>{type, length, data}</em>. This
* class represents such tagged values as they have been read (or constructed),
* and provides structured access to the encoded data.
*
* <P>At this time, this class supports only a subset of the types of DER
* data encodings which are defined. That subset is sufficient for parsing
* most X.509 certificates, and working with selected additional formats
* (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data).
*
* A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3
* and RFC 5280, section 8, we assume that this kind of string will contain
* ISO-8859-1 characters only.
*
*
* @author David Brownell
* @author Amit Kapoor
* @author Hemma Prafullchandra
*/
public class DerValue {
/** The tag class types */
public static final byte TAG_UNIVERSAL = (byte)0x000;
public static final byte TAG_APPLICATION = (byte)0x040;
public static final byte TAG_CONTEXT = (byte)0x080;
public static final byte TAG_PRIVATE = (byte)0x0c0;
/** The DER tag of the value; one of the tag_ constants. */
public byte tag;
protected DerInputBuffer buffer;
/**
* The DER-encoded data of the value, never null
*/
public final DerInputStream data;
private int length;
/*
* The type starts at the first byte of the encoding, and
* is one of these tag_* values. That may be all the type
* data that is needed.
*/
/*
* These tags are the "universal" tags ... they mean the same
* in all contexts. (Mask with 0x1f -- five bits.)
*/
/** Tag value indicating an ASN.1 "BOOLEAN" value. */
public static final byte tag_Boolean = 0x01;
/** Tag value indicating an ASN.1 "INTEGER" value. */
public static final byte tag_Integer = 0x02;
/** Tag value indicating an ASN.1 "BIT STRING" value. */
public static final byte tag_BitString = 0x03;
/** Tag value indicating an ASN.1 "OCTET STRING" value. */
public static final byte tag_OctetString = 0x04;
/** Tag value indicating an ASN.1 "NULL" value. */
public static final byte tag_Null = 0x05;
/** Tag value indicating an ASN.1 "OBJECT IDENTIFIER" value. */
public static final byte tag_ObjectId = 0x06;
/** Tag value including an ASN.1 "ENUMERATED" value */
public static final byte tag_Enumerated = 0x0A;
/** Tag value indicating an ASN.1 "UTF8String" value. */
public static final byte tag_UTF8String = 0x0C;
/** Tag value including a "printable" string */
public static final byte tag_PrintableString = 0x13;
/** Tag value including a "teletype" string */
public static final byte tag_T61String = 0x14;
/** Tag value including an ASCII string */
public static final byte tag_IA5String = 0x16;
/** Tag value indicating an ASN.1 "UTCTime" value. */
public static final byte tag_UtcTime = 0x17;
/** Tag value indicating an ASN.1 "GeneralizedTime" value. */
public static final byte tag_GeneralizedTime = 0x18;
/** Tag value indicating an ASN.1 "GenerallString" value. */
public static final byte tag_GeneralString = 0x1B;
/** Tag value indicating an ASN.1 "UniversalString" value. */
public static final byte tag_UniversalString = 0x1C;
/** Tag value indicating an ASN.1 "BMPString" value. */
public static final byte tag_BMPString = 0x1E;
// CONSTRUCTED seq/set
/**
* Tag value indicating an ASN.1
* "SEQUENCE" (zero to N elements, order is significant).
*/
public static final byte tag_Sequence = 0x30;
/**
* Tag value indicating an ASN.1
* "SEQUENCE OF" (one to N elements, order is significant).
*/
public static final byte tag_SequenceOf = 0x30;
/**
* Tag value indicating an ASN.1
* "SET" (zero to N members, order does not matter).
*/
public static final byte tag_Set = 0x31;
/**
* Tag value indicating an ASN.1
* "SET OF" (one to N members, order does not matter).
*/
public static final byte tag_SetOf = 0x31;
/*
* These values are the high order bits for the other kinds of tags.
*/
/**
* Returns true if the tag class is UNIVERSAL.
*/
public boolean isUniversal() { return ((tag & 0x0c0) == 0x000); }
/**
* Returns true if the tag class is APPLICATION.
*/
public boolean isApplication() { return ((tag & 0x0c0) == 0x040); }
/**
* Returns true iff the CONTEXT SPECIFIC bit is set in the type tag.
* This is associated with the ASN.1 "DEFINED BY" syntax.
*/
public boolean isContextSpecific() { return ((tag & 0x0c0) == 0x080); }
/**
* Returns true iff the CONTEXT SPECIFIC TAG matches the passed tag.
*/
public boolean isContextSpecific(byte cntxtTag) {
if (!isContextSpecific()) {
return false;
}
return ((tag & 0x01f) == cntxtTag);
}
boolean isPrivate() { return ((tag & 0x0c0) == 0x0c0); }
/** Returns true iff the CONSTRUCTED bit is set in the type tag. */
public boolean isConstructed() { return ((tag & 0x020) == 0x020); }
/**
* Returns true iff the CONSTRUCTED TAG matches the passed tag.
*/
public boolean isConstructed(byte constructedTag) {
if (!isConstructed()) {
return false;
}
return ((tag & 0x01f) == constructedTag);
}
/**
* Creates a PrintableString or UTF8string DER value from a string
*/
public DerValue(String value) throws IOException {
boolean isPrintableString = true;
for (int i = 0; i < value.length(); i++) {
if (!isPrintableStringChar(value.charAt(i))) {
isPrintableString = false;
break;
}
}
data = init(isPrintableString ? tag_PrintableString : tag_UTF8String, value);
}
/**
* Creates a string type DER value from a String object
* @param stringTag the tag for the DER value to create
* @param value the String object to use for the DER value
*/
public DerValue(byte stringTag, String value) throws IOException {
data = init(stringTag, value);
}
// Creates a DerValue from a tag and some DER-encoded data w/ additional
// arg to control whether DER checks are enforced.
DerValue(byte tag, byte[] data, boolean allowBER) {
this.tag = tag;
buffer = new DerInputBuffer(data.clone(), allowBER);
length = data.length;
this.data = new DerInputStream(buffer);
this.data.mark(Integer.MAX_VALUE);
}
/**
* Creates a DerValue from a tag and some DER-encoded data.
*
* @param tag the DER type tag
* @param data the DER-encoded data
*/
public DerValue(byte tag, byte[] data) {
this(tag, data, true);
}
/*
* package private
*/
DerValue(DerInputBuffer in) throws IOException {
// XXX must also parse BER-encoded constructed
// values such as sequences, sets...
tag = (byte)in.read();
byte lenByte = (byte)in.read();
length = DerInputStream.getLength(lenByte, in);
if (length == -1) { // indefinite length encoding found
DerInputBuffer inbuf = in.dup();
int readLen = inbuf.available();
int offset = 2; // for tag and length bytes
byte[] indefData = new byte[readLen + offset];
indefData[0] = tag;
indefData[1] = lenByte;
DataInputStream dis = new DataInputStream(inbuf);
dis.readFully(indefData, offset, readLen);
dis.close();
DerIndefLenConverter derIn = new DerIndefLenConverter();
inbuf = new DerInputBuffer(derIn.convert(indefData), in.allowBER);
if (tag != inbuf.read())
throw new IOException
("Indefinite length encoding not supported");
length = DerInputStream.getDefiniteLength(inbuf);
buffer = inbuf.dup();
buffer.truncate(length);
data = new DerInputStream(buffer);
// indefinite form is encoded by sending a length field with a
// length of 0. - i.e. [1000|0000].
// the object is ended by sending two zero bytes.
in.skip(length + offset);
} else {
buffer = in.dup();
buffer.truncate(length);
data = new DerInputStream(buffer);
in.skip(length);
}
}
// Get an ASN.1/DER encoded datum from a buffer w/ additional
// arg to control whether DER checks are enforced.
DerValue(byte[] buf, boolean allowBER) throws IOException {
data = init(true, new ByteArrayInputStream(buf), allowBER);
}
/**
* Get an ASN.1/DER encoded datum from a buffer. The
* entire buffer must hold exactly one datum, including
* its tag and length.
*
* @param buf buffer holding a single DER-encoded datum.
*/
public DerValue(byte[] buf) throws IOException {
this(buf, true);
}
// Get an ASN.1/DER encoded datum from part of a buffer w/ additional
// arg to control whether DER checks are enforced.
DerValue(byte[] buf, int offset, int len, boolean allowBER)
throws IOException {
data = init(true, new ByteArrayInputStream(buf, offset, len), allowBER);
}
/**
* Get an ASN.1/DER encoded datum from part of a buffer.
* That part of the buffer must hold exactly one datum, including
* its tag and length.
*
* @param buf the buffer
* @param offset start point of the single DER-encoded dataum
* @param len how many bytes are in the encoded datum
*/
public DerValue(byte[] buf, int offset, int len) throws IOException {
this(buf, offset, len, true);
}
// Get an ASN1/DER encoded datum from an input stream w/ additional
// arg to control whether DER checks are enforced.
DerValue(InputStream in, boolean allowBER) throws IOException {
data = init(false, in, allowBER);
}
/**
* Get an ASN1/DER encoded datum from an input stream. The
* stream may have additional data following the encoded datum.
* In case of indefinite length encoded datum, the input stream
* must hold only one datum.
*
* @param in the input stream holding a single DER datum,
* which may be followed by additional data
*/
public DerValue(InputStream in) throws IOException {
this(in, true);
}
private DerInputStream init(byte stringTag, String value)
throws IOException {
String enc = null;
tag = stringTag;
switch (stringTag) {
case tag_PrintableString:
case tag_IA5String:
case tag_GeneralString:
enc = "ASCII";
break;
case tag_T61String:
enc = "ISO-8859-1";
break;
case tag_BMPString:
enc = "UnicodeBigUnmarked";
break;
case tag_UTF8String:
enc = "UTF8";
break;
// TBD: Need encoder for UniversalString before it can
// be handled.
default:
throw new IllegalArgumentException("Unsupported DER string type");
}
byte[] buf = value.getBytes(enc);
length = buf.length;
buffer = new DerInputBuffer(buf, true);
DerInputStream result = new DerInputStream(buffer);
result.mark(Integer.MAX_VALUE);
return result;
}
/*
* helper routine
*/
private DerInputStream init(boolean fullyBuffered, InputStream in,
boolean allowBER) throws IOException {
tag = (byte)in.read();
byte lenByte = (byte)in.read();
length = DerInputStream.getLength(lenByte, in);
if (length == -1) { // indefinite length encoding found
int readLen = in.available();
int offset = 2; // for tag and length bytes
byte[] indefData = new byte[readLen + offset];
indefData[0] = tag;
indefData[1] = lenByte;
DataInputStream dis = new DataInputStream(in);
dis.readFully(indefData, offset, readLen);
dis.close();
DerIndefLenConverter derIn = new DerIndefLenConverter();
in = new ByteArrayInputStream(derIn.convert(indefData));
if (tag != in.read())
throw new IOException
("Indefinite length encoding not supported");
length = DerInputStream.getDefiniteLength(in);
}
if (fullyBuffered && in.available() != length)
throw new IOException("extra data given to DerValue constructor");
byte[] bytes = IOUtils.readFully(in, length, true);
buffer = new DerInputBuffer(bytes, allowBER);
return new DerInputStream(buffer);
}
/**
* Encode an ASN1/DER encoded datum onto a DER output stream.
*/
public void encode(DerOutputStream out)
throws IOException {
out.write(tag);
out.putLength(length);
// XXX yeech, excess copies ... DerInputBuffer.write(OutStream)
if (length > 0) {
byte[] value = new byte[length];
// always synchronized on data
synchronized (data) {
buffer.reset();
if (buffer.read(value) != length) {
throw new IOException("short DER value read (encode)");
}
out.write(value);
}
}
}
public final DerInputStream getData() {
return data;
}
public final byte getTag() {
return tag;
}
/**
* Returns an ASN.1 BOOLEAN
*
* @return the boolean held in this DER value
*/
public boolean getBoolean() throws IOException {
if (tag != tag_Boolean) {
throw new IOException("DerValue.getBoolean, not a BOOLEAN " + tag);
}
if (length != 1) {
throw new IOException("DerValue.getBoolean, invalid length "
+ length);
}
if (buffer.read() != 0) {
return true;
}
return false;
}
/**
* Returns an ASN.1 OBJECT IDENTIFIER.
*
* @return the OID held in this DER value
*/
public ObjectIdentifier getOID() throws IOException {
if (tag != tag_ObjectId)
throw new IOException("DerValue.getOID, not an OID " + tag);
return new ObjectIdentifier(buffer);
}
private byte[] append(byte[] a, byte[] b) {
if (a == null)
return b;
byte[] ret = new byte[a.length + b.length];
System.arraycopy(a, 0, ret, 0, a.length);
System.arraycopy(b, 0, ret, a.length, b.length);
return ret;
}
/**
* Returns an ASN.1 OCTET STRING
*
* @return the octet string held in this DER value
*/
public byte[] getOctetString() throws IOException {
byte[] bytes;
if (tag != tag_OctetString && !isConstructed(tag_OctetString)) {
throw new IOException(
"DerValue.getOctetString, not an Octet String: " + tag);
}
bytes = new byte[length];
// Note: do not tempt to call buffer.read(bytes) at all. There's a
// known bug that it returns -1 instead of 0.
if (length == 0) {
return bytes;
}
if (buffer.read(bytes) != length)
throw new IOException("short read on DerValue buffer");
if (isConstructed()) {
DerInputStream in = new DerInputStream(bytes, 0, bytes.length,
buffer.allowBER);
bytes = null;
while (in.available() != 0) {
bytes = append(bytes, in.getOctetString());
}
}
return bytes;
}
/**
* Returns an ASN.1 INTEGER value as an integer.
*
* @return the integer held in this DER value.
*/
public int getInteger() throws IOException {
if (tag != tag_Integer) {
throw new IOException("DerValue.getInteger, not an int " + tag);
}
return buffer.getInteger(data.available());
}
/**
* Returns an ASN.1 INTEGER value as a BigInteger.
*
* @return the integer held in this DER value as a BigInteger.
*/
public BigInteger getBigInteger() throws IOException {
if (tag != tag_Integer)
throw new IOException("DerValue.getBigInteger, not an int " + tag);
return buffer.getBigInteger(data.available(), false);
}
/**
* Returns an ASN.1 INTEGER value as a positive BigInteger.
* This is just to deal with implementations that incorrectly encode
* some values as negative.
*
* @return the integer held in this DER value as a BigInteger.
*/
public BigInteger getPositiveBigInteger() throws IOException {
if (tag != tag_Integer)
throw new IOException("DerValue.getBigInteger, not an int " + tag);
return buffer.getBigInteger(data.available(), true);
}
/**
* Returns an ASN.1 ENUMERATED value.
*
* @return the integer held in this DER value.
*/
public int getEnumerated() throws IOException {
if (tag != tag_Enumerated) {
throw new IOException("DerValue.getEnumerated, incorrect tag: "
+ tag);
}
return buffer.getInteger(data.available());
}
/**
* Returns an ASN.1 BIT STRING value. The bit string must be byte-aligned.
*
* @return the bit string held in this value
*/
public byte[] getBitString() throws IOException {
if (tag != tag_BitString)
throw new IOException(
"DerValue.getBitString, not a bit string " + tag);
return buffer.getBitString();
}
/**
* Returns an ASN.1 BIT STRING value that need not be byte-aligned.
*
* @return a BitArray representing the bit string held in this value
*/
public BitArray getUnalignedBitString() throws IOException {
if (tag != tag_BitString)
throw new IOException(
"DerValue.getBitString, not a bit string " + tag);
return buffer.getUnalignedBitString();
}
/**
* Returns the name component as a Java string, regardless of its
* encoding restrictions (ASCII, T61, Printable, IA5, BMP, UTF8).
*/
// TBD: Need encoder for UniversalString before it can be handled.
public String getAsString() throws IOException {
if (tag == tag_UTF8String)
return getUTF8String();
else if (tag == tag_PrintableString)
return getPrintableString();
else if (tag == tag_T61String)
return getT61String();
else if (tag == tag_IA5String)
return getIA5String();
/*
else if (tag == tag_UniversalString)
return getUniversalString();
*/
else if (tag == tag_BMPString)
return getBMPString();
else if (tag == tag_GeneralString)
return getGeneralString();
else
return null;
}
/**
* Returns an ASN.1 BIT STRING value, with the tag assumed implicit
* based on the parameter. The bit string must be byte-aligned.
*
* @param tagImplicit if true, the tag is assumed implicit.
* @return the bit string held in this value
*/
public byte[] getBitString(boolean tagImplicit) throws IOException {
if (!tagImplicit) {
if (tag != tag_BitString)
throw new IOException("DerValue.getBitString, not a bit string "
+ tag);
}
return buffer.getBitString();
}
/**
* Returns an ASN.1 BIT STRING value, with the tag assumed implicit
* based on the parameter. The bit string need not be byte-aligned.
*
* @param tagImplicit if true, the tag is assumed implicit.
* @return the bit string held in this value
*/
public BitArray getUnalignedBitString(boolean tagImplicit)
throws IOException {
if (!tagImplicit) {
if (tag != tag_BitString)
throw new IOException("DerValue.getBitString, not a bit string "
+ tag);
}
return buffer.getUnalignedBitString();
}
/**
* Helper routine to return all the bytes contained in the
* DerInputStream associated with this object.
*/
public byte[] getDataBytes() throws IOException {
byte[] retVal = new byte[length];
synchronized (data) {
data.reset();
data.getBytes(retVal);
}
return retVal;
}
/**
* Returns an ASN.1 STRING value
*
* @return the printable string held in this value
*/
public String getPrintableString()
throws IOException {
if (tag != tag_PrintableString)
throw new IOException(
"DerValue.getPrintableString, not a string " + tag);
return new String(getDataBytes(), "ASCII");
}
/**
* Returns an ASN.1 T61 (Teletype) STRING value
*
* @return the teletype string held in this value
*/
public String getT61String() throws IOException {
if (tag != tag_T61String)
throw new IOException(
"DerValue.getT61String, not T61 " + tag);
return new String(getDataBytes(), "ISO-8859-1");
}
/**
* Returns an ASN.1 IA5 (ASCII) STRING value
*
* @return the ASCII string held in this value
*/
public String getIA5String() throws IOException {
if (tag != tag_IA5String)
throw new IOException(
"DerValue.getIA5String, not IA5 " + tag);
return new String(getDataBytes(), "ASCII");
}
/**
* Returns the ASN.1 BMP (Unicode) STRING value as a Java string.
*
* @return a string corresponding to the encoded BMPString held in
* this value
*/
public String getBMPString() throws IOException {
if (tag != tag_BMPString)
throw new IOException(
"DerValue.getBMPString, not BMP " + tag);
// BMPString is the same as Unicode in big endian, unmarked
// format.
return new String(getDataBytes(), "UnicodeBigUnmarked");
}
/**
* Returns the ASN.1 UTF-8 STRING value as a Java String.
*
* @return a string corresponding to the encoded UTF8String held in
* this value
*/
public String getUTF8String() throws IOException {
if (tag != tag_UTF8String)
throw new IOException(
"DerValue.getUTF8String, not UTF-8 " + tag);
return new String(getDataBytes(), "UTF8");
}
/**
* Returns the ASN.1 GENERAL STRING value as a Java String.
*
* @return a string corresponding to the encoded GeneralString held in
* this value
*/
public String getGeneralString() throws IOException {
if (tag != tag_GeneralString)
throw new IOException(
"DerValue.getGeneralString, not GeneralString " + tag);
return new String(getDataBytes(), "ASCII");
}
/**
* Returns a Date if the DerValue is UtcTime.
*
* @return the Date held in this DER value
*/
public Date getUTCTime() throws IOException {
if (tag != tag_UtcTime) {
throw new IOException("DerValue.getUTCTime, not a UtcTime: " + tag);
}
return buffer.getUTCTime(data.available());
}
/**
* Returns a Date if the DerValue is GeneralizedTime.
*
* @return the Date held in this DER value
*/
public Date getGeneralizedTime() throws IOException {
if (tag != tag_GeneralizedTime) {
throw new IOException(
"DerValue.getGeneralizedTime, not a GeneralizedTime: " + tag);
}
return buffer.getGeneralizedTime(data.available());
}
/**
* Bitwise equality comparison. DER encoded values have a single
* encoding, so that bitwise equality of the encoded values is an
* efficient way to establish equivalence of the unencoded values.
*
* @param o the object being compared with this one
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof DerValue)) {
return false;
}
DerValue other = (DerValue) o;
if (tag != other.tag) {
return false;
}
if (data == other.data) {
return true;
}
// make sure the order of lock is always consistent to avoid a deadlock
return (System.identityHashCode(this.data)
> System.identityHashCode(other.data)) ?
doEquals(this, other):
doEquals(other, this);
}
/**
* Helper for public method equals()
*/
private static boolean doEquals(DerValue d1, DerValue d2) {
synchronized (d1.data) {
synchronized (d2.data) {
d1.data.reset();
d2.data.reset();
return d1.buffer.equals(d2.buffer);
}
}
}
/**
* Returns a printable representation of the value.
*
* @return printable representation of the value
*/
@Override
public String toString() {
try {
String str = getAsString();
if (str != null)
return "\"" + str + "\"";
if (tag == tag_Null)
return "[DerValue, null]";
if (tag == tag_ObjectId)
return "OID." + getOID();
// integers
else
return "[DerValue, tag = " + tag
+ ", length = " + length + "]";
} catch (IOException e) {
throw new IllegalArgumentException("misformatted DER value");
}
}
/**
* Returns a DER-encoded value, such that if it's passed to the
* DerValue constructor, a value equivalent to "this" is returned.
*
* @return DER-encoded value, including tag and length.
*/
public byte[] toByteArray() throws IOException {
DerOutputStream out = new DerOutputStream();
encode(out);
data.reset();
return out.toByteArray();
}
/**
* For "set" and "sequence" types, this function may be used
* to return a DER stream of the members of the set or sequence.
* This operation is not supported for primitive types such as
* integers or bit strings.
*/
public DerInputStream toDerInputStream() throws IOException {
if (tag == tag_Sequence || tag == tag_Set)
return new DerInputStream(buffer);
throw new IOException("toDerInputStream rejects tag type " + tag);
}
/**
* Get the length of the encoded value.
*/
public int length() {
return length;
}
/**
* Determine if a character is one of the permissible characters for
* PrintableString:
* A-Z, a-z, 0-9, space, apostrophe (39), left and right parentheses,
* plus sign, comma, hyphen, period, slash, colon, equals sign,
* and question mark.
*
* Characters that are *not* allowed in PrintableString include
* exclamation point, quotation mark, number sign, dollar sign,
* percent sign, ampersand, asterisk, semicolon, less than sign,
* greater than sign, at sign, left and right square brackets,
* backslash, circumflex (94), underscore, back quote (96),
* left and right curly brackets, vertical line, tilde,
* and the control codes (0-31 and 127).
*
* This list is based on X.680 (the ASN.1 spec).
*/
public static boolean isPrintableStringChar(char ch) {
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9')) {
return true;
} else {
switch (ch) {
case ' ': /* space */
case '\'': /* apostrophe */
case '(': /* left paren */
case ')': /* right paren */
case '+': /* plus */
case ',': /* comma */
case '-': /* hyphen */
case '.': /* period */
case '/': /* slash */
case ':': /* colon */
case '=': /* equals */
case '?': /* question mark */
return true;
default:
return false;
}
}
}
/**
* Create the tag of the attribute.
*
* @param tagClass the tag class type, one of UNIVERSAL, CONTEXT,
* APPLICATION or PRIVATE
* @param form if true, the value is constructed, otherwise it
* is primitive.
* @param val the tag value
*/
public static byte createTag(byte tagClass, boolean form, byte val) {
byte tag = (byte)(tagClass | val);
if (form) {
tag |= (byte)0x20;
}
return (tag);
}
/**
* Set the tag of the attribute. Commonly used to reset the
* tag value used for IMPLICIT encodings.
*
* @param tag the tag value
*/
public void resetTag(byte tag) {
this.tag = tag;
}
/**
* Returns a hashcode for this DerValue.
*
* @return a hashcode for this DerValue.
*/
@Override
public int hashCode() {
return toString().hashCode();
}
}

View file

@ -0,0 +1,903 @@
/*
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import sun.security.validator.Validator;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Collection;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Algorithm constraints for disabled algorithms property
*
* See the "jdk.certpath.disabledAlgorithms" specification in java.security
* for the syntax of the disabled algorithm string.
*/
public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
private static final Debug debug = Debug.getInstance("certpath");
// the known security property, jdk.certpath.disabledAlgorithms
public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
"jdk.certpath.disabledAlgorithms";
// the known security property, jdk.tls.disabledAlgorithms
public static final String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms";
// the known security property, jdk.jar.disabledAlgorithms
public static final String PROPERTY_JAR_DISABLED_ALGS =
"jdk.jar.disabledAlgorithms";
private final String[] disabledAlgorithms;
private final Constraints algorithmConstraints;
/**
* Initialize algorithm constraints with the specified security property.
*
* @param propertyName the security property name that define the disabled
* algorithm constraints
*/
public DisabledAlgorithmConstraints(String propertyName) {
this(propertyName, new AlgorithmDecomposer());
}
/**
* Initialize algorithm constraints with the specified security property
* for a specific usage type.
*
* @param propertyName the security property name that define the disabled
* algorithm constraints
* @param decomposer an alternate AlgorithmDecomposer.
*/
public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
disabledAlgorithms = getAlgorithms(propertyName);
algorithmConstraints = new Constraints(disabledAlgorithms);
}
/*
* This only checks if the algorithm has been completely disabled. If
* there are keysize or other limit, this method allow the algorithm.
*/
@Override
public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) {
if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) {
return false;
}
if (parameters != null) {
return algorithmConstraints.permits(algorithm, parameters);
}
return true;
}
/*
* Checks if the key algorithm has been disabled or constraints have been
* placed on the key.
*/
@Override
public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
return checkConstraints(primitives, "", key, null);
}
/*
* Checks if the key algorithm has been disabled or if constraints have
* been placed on the key.
*/
@Override
public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) {
if (algorithm == null || algorithm.length() == 0) {
throw new IllegalArgumentException("No algorithm name specified");
}
return checkConstraints(primitives, algorithm, key, parameters);
}
public final void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
permits(cp.getAlgorithm(), cp);
}
public final void permits(String algorithm, Key key,
AlgorithmParameters params, String variant)
throws CertPathValidatorException {
permits(algorithm, new ConstraintsParameters(algorithm, params, key,
(variant == null) ? Validator.VAR_GENERIC : variant));
}
/*
* Check if a x509Certificate object is permitted. Check if all
* algorithms are allowed, certificate constraints, and the
* public key against key constraints.
*
* Uses new style permit() which throws exceptions.
*/
public final void permits(String algorithm, ConstraintsParameters cp)
throws CertPathValidatorException {
algorithmConstraints.permits(algorithm, cp);
}
// Check if a string is contained inside the property
public boolean checkProperty(String param) {
param = param.toLowerCase(Locale.ENGLISH);
for (String block : disabledAlgorithms) {
if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
return true;
}
}
return false;
}
// Check algorithm constraints with key and algorithm
private boolean checkConstraints(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) {
// check the key parameter, it cannot be null.
if (key == null) {
throw new IllegalArgumentException("The key cannot be null");
}
// check the signature algorithm with parameters
if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) {
return false;
}
}
// check the key algorithm
if (!permits(primitives, key.getAlgorithm(), null)) {
return false;
}
// check the key constraints
return algorithmConstraints.permits(key);
}
/**
* Key and Certificate Constraints
*
* The complete disabling of an algorithm is not handled by Constraints or
* Constraint classes. That is addressed with
* permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
*
* When passing a Key to permit(), the boolean return values follow the
* same as the interface class AlgorithmConstraints.permit(). This is to
* maintain compatibility:
* 'true' means the operation is allowed.
* 'false' means it failed the constraints and is disallowed.
*
* When passing ConstraintsParameters through permit(), an exception
* will be thrown on a failure to better identify why the operation was
* disallowed.
*/
private static class Constraints {
private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
private static class Holder {
private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
"denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
}
public Constraints(String[] constraintArray) {
for (String constraintEntry : constraintArray) {
if (constraintEntry == null || constraintEntry.isEmpty()) {
continue;
}
constraintEntry = constraintEntry.trim();
if (debug != null) {
debug.println("Constraints: " + constraintEntry);
}
// Check if constraint is a complete disabling of an
// algorithm or has conditions.
int space = constraintEntry.indexOf(' ');
String algorithm = AlgorithmDecomposer.hashName(
((space > 0 ? constraintEntry.substring(0, space) :
constraintEntry).
toUpperCase(Locale.ENGLISH)));
List<Constraint> constraintList =
constraintsMap.getOrDefault(algorithm,
new ArrayList<>(1));
// Consider the impact of algorithm aliases.
for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {
constraintsMap.putIfAbsent(alias, constraintList);
}
if (space <= 0) {
constraintList.add(new DisabledConstraint(algorithm));
continue;
}
String policy = constraintEntry.substring(space + 1);
// Convert constraint conditions into Constraint classes
Constraint c, lastConstraint = null;
// Allow only one jdkCA entry per constraint entry
boolean jdkCALimit = false;
// Allow only one denyAfter entry per constraint entry
boolean denyAfterLimit = false;
for (String entry : policy.split("&")) {
entry = entry.trim();
Matcher matcher;
if (entry.startsWith("keySize")) {
if (debug != null) {
debug.println("Constraints set to keySize: " +
entry);
}
StringTokenizer tokens = new StringTokenizer(entry);
if (!"keySize".equals(tokens.nextToken())) {
throw new IllegalArgumentException("Error in " +
"security property. Constraint unknown: " +
entry);
}
c = new KeySizeConstraint(algorithm,
KeySizeConstraint.Operator.of(tokens.nextToken()),
Integer.parseInt(tokens.nextToken()));
} else if (entry.equalsIgnoreCase("jdkCA")) {
if (debug != null) {
debug.println("Constraints set to jdkCA.");
}
if (jdkCALimit) {
throw new IllegalArgumentException("Only one " +
"jdkCA entry allowed in property. " +
"Constraint: " + constraintEntry);
}
c = new jdkCAConstraint(algorithm);
jdkCALimit = true;
} else if (entry.startsWith("denyAfter") &&
(matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
.matches()) {
if (debug != null) {
debug.println("Constraints set to denyAfter");
}
if (denyAfterLimit) {
throw new IllegalArgumentException("Only one " +
"denyAfter entry allowed in property. " +
"Constraint: " + constraintEntry);
}
int year = Integer.parseInt(matcher.group(1));
int month = Integer.parseInt(matcher.group(2));
int day = Integer.parseInt(matcher.group(3));
c = new DenyAfterConstraint(algorithm, year, month,
day);
denyAfterLimit = true;
} else if (entry.startsWith("usage")) {
String s[] = (entry.substring(5)).trim().split(" ");
c = new UsageConstraint(algorithm, s);
if (debug != null) {
debug.println("Constraints usage length is " + s.length);
}
} else {
throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry);
}
// Link multiple conditions for a single constraint
// into a linked list.
if (lastConstraint == null) {
constraintList.add(c);
} else {
lastConstraint.nextConstraint = c;
}
lastConstraint = c;
}
}
}
// Get applicable constraints based off the signature algorithm
private List<Constraint> getConstraints(String algorithm) {
return constraintsMap.get(algorithm);
}
// Check if KeySizeConstraints permit the specified key
public boolean permits(Key key) {
List<Constraint> list = getConstraints(key.getAlgorithm());
if (list == null) {
return true;
}
for (Constraint constraint : list) {
if (!constraint.permits(key)) {
if (debug != null) {
debug.println("keySizeConstraint: failed key " +
"constraint check " + KeyUtil.getKeySize(key));
}
return false;
}
}
return true;
}
// Check if constraints permit this AlgorithmParameters.
public boolean permits(String algorithm, AlgorithmParameters aps) {
List<Constraint> list = getConstraints(algorithm);
if (list == null) {
return true;
}
for (Constraint constraint : list) {
if (!constraint.permits(aps)) {
if (debug != null) {
debug.println("keySizeConstraint: failed algorithm " +
"parameters constraint check " + aps);
}
return false;
}
}
return true;
}
// Check if constraints permit this cert.
public void permits(String algorithm, ConstraintsParameters cp)
throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
if (debug != null) {
debug.println("Constraints.permits(): " + algorithm +
" Variant: " + cp.getVariant());
}
// Get all signature algorithms to check for constraints
Set<String> algorithms = new HashSet<>();
if (algorithm != null) {
algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
}
// Attempt to add the public key algorithm if cert provided
if (cert != null) {
algorithms.add(cert.getPublicKey().getAlgorithm());
}
if (cp.getPublicKey() != null) {
algorithms.add(cp.getPublicKey().getAlgorithm());
}
// Check all applicable constraints
for (String alg : algorithms) {
List<Constraint> list = getConstraints(alg);
if (list == null) {
continue;
}
for (Constraint constraint : list) {
constraint.permits(cp);
}
}
}
}
/**
* This abstract Constraint class for algorithm-based checking
* may contain one or more constraints. If the '&' on the {@Security}
* property is used, multiple constraints have been grouped together
* requiring all the constraints to fail for the check to be disallowed.
*
* If the class contains multiple constraints, the next constraint
* is stored in {@code nextConstraint} in linked-list fashion.
*/
private abstract static class Constraint {
String algorithm;
Constraint nextConstraint = null;
// operator
enum Operator {
EQ, // "=="
NE, // "!="
LT, // "<"
LE, // "<="
GT, // ">"
GE; // ">="
static Operator of(String s) {
switch (s) {
case "==":
return EQ;
case "!=":
return NE;
case "<":
return LT;
case "<=":
return LE;
case ">":
return GT;
case ">=":
return GE;
}
throw new IllegalArgumentException("Error in security " +
"property. " + s + " is not a legal Operator");
}
}
/**
* Check if an algorithm constraint is permitted with a given key.
*
* If the check inside of {@code permit()} fails, it must call
* {@code next()} with the same {@code Key} parameter passed if
* multiple constraints need to be checked.
*
* @param key Public key
* @return 'true' if constraint is allowed, 'false' if disallowed.
*/
public boolean permits(Key key) {
return true;
}
/**
* Check if the algorithm constraint permits a given cryptographic
* parameters.
*
* @param parameters the cryptographic parameters
* @return 'true' if the cryptographic parameters is allowed,
* 'false' ortherwise.
*/
public boolean permits(AlgorithmParameters parameters) {
return true;
}
/**
* Check if an algorithm constraint is permitted with a given
* ConstraintsParameters.
*
* If the check inside of {@code permits()} fails, it must call
* {@code next()} with the same {@code ConstraintsParameters}
* parameter passed if multiple constraints need to be checked.
*
* @param cp CertConstraintParameter containing certificate info
* @throws CertPathValidatorException if constraint disallows.
*
*/
public abstract void permits(ConstraintsParameters cp)
throws CertPathValidatorException;
/**
* Recursively check if the constraints are allowed.
*
* If {@code nextConstraint} is non-null, this method will
* call {@code nextConstraint}'s {@code permits()} to check if the
* constraint is allowed or denied. If the constraint's
* {@code permits()} is allowed, this method will exit this and any
* recursive next() calls, returning 'true'. If the constraints called
* were disallowed, the last constraint will throw
* {@code CertPathValidatorException}.
*
* @param cp ConstraintsParameters
* @return 'true' if constraint allows the operation, 'false' if
* we are at the end of the constraint list or,
* {@code nextConstraint} is null.
*/
boolean next(ConstraintsParameters cp)
throws CertPathValidatorException {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return true;
}
return false;
}
/**
* Recursively check if this constraint is allowed,
*
* If {@code nextConstraint} is non-null, this method will
* call {@code nextConstraint}'s {@code permit()} to check if the
* constraint is allowed or denied. If the constraint's
* {@code permit()} is allowed, this method will exit this and any
* recursive next() calls, returning 'true'. If the constraints
* called were disallowed the check will exit with 'false'.
*
* @param key Public key
* @return 'true' if constraint allows the operation, 'false' if
* the constraint denies the operation.
*/
boolean next(Key key) {
if (nextConstraint != null && nextConstraint.permits(key)) {
return true;
}
return false;
}
String extendedMsg(ConstraintsParameters cp) {
return (cp.getCertificate() == null ? "." :
" used with certificate: " +
cp.getCertificate().getSubjectX500Principal() +
(cp.getVariant() != Validator.VAR_GENERIC ?
". Usage was " + cp.getVariant() : "."));
}
}
/*
* This class contains constraints dealing with the certificate chain
* of the certificate.
*/
private static class jdkCAConstraint extends Constraint {
jdkCAConstraint(String algo) {
algorithm = algo;
}
/*
* Check if ConstraintsParameters has a trusted match, if it does
* call next() for any following constraints. If it does not, exit
* as this constraint(s) does not restrict the operation.
*/
@Override
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
if (debug != null) {
debug.println("jdkCAConstraints.permits(): " + algorithm);
}
// Check chain has a trust anchor in cacerts
if (cp.isTrustedMatch()) {
if (next(cp)) {
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
"anchor limits. " + algorithm + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
/*
* This class handles the denyAfter constraint. The date is in the UTC/GMT
* timezone.
*/
private static class DenyAfterConstraint extends Constraint {
private Date denyAfterDate;
private static final SimpleDateFormat dateFormat =
new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy");
DenyAfterConstraint(String algo, int year, int month, int day) {
Calendar c;
algorithm = algo;
if (debug != null) {
debug.println("DenyAfterConstraint read in as: year " +
year + ", month = " + month + ", day = " + day);
}
c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT"))
.setDate(year, month - 1, day).build();
if (year > c.getActualMaximum(Calendar.YEAR) ||
year < c.getActualMinimum(Calendar.YEAR)) {
throw new IllegalArgumentException(
"Invalid year given in constraint: " + year);
}
if ((month - 1) > c.getActualMaximum(Calendar.MONTH) ||
(month - 1) < c.getActualMinimum(Calendar.MONTH)) {
throw new IllegalArgumentException(
"Invalid month given in constraint: " + month);
}
if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) ||
day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) {
throw new IllegalArgumentException(
"Invalid Day of Month given in constraint: " + day);
}
denyAfterDate = c.getTime();
if (debug != null) {
debug.println("DenyAfterConstraint date set to: " +
dateFormat.format(denyAfterDate));
}
}
/*
* Checking that the provided date is not beyond the constraint date.
* The provided date can be the PKIXParameter date if given,
* otherwise it is the current date.
*
* If the constraint disallows, call next() for any following
* constraints. Throw an exception if this is the last constraint.
*/
@Override
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
Date currentDate;
String errmsg;
if (cp.getJARTimestamp() != null) {
currentDate = cp.getJARTimestamp().getTimestamp();
errmsg = "JAR Timestamp date: ";
} else if (cp.getPKIXParamDate() != null) {
currentDate = cp.getPKIXParamDate();
errmsg = "PKIXParameter date: ";
} else {
currentDate = new Date();
errmsg = "Current date: ";
}
if (!denyAfterDate.after(currentDate)) {
if (next(cp)) {
return;
}
throw new CertPathValidatorException(
"denyAfter constraint check failed: " + algorithm +
" used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; " + errmsg +
dateFormat.format(currentDate) + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
/*
* Return result if the constraint's date is beyond the current date
* in UTC timezone.
*/
@Override
public boolean permits(Key key) {
if (next(key)) {
return true;
}
if (debug != null) {
debug.println("DenyAfterConstraints.permits(): " + algorithm);
}
return denyAfterDate.after(new Date());
}
}
/*
* The usage constraint is for the "usage" keyword. It checks against the
* variant value in ConstraintsParameters.
*/
private static class UsageConstraint extends Constraint {
String[] usages;
UsageConstraint(String algorithm, String[] usages) {
this.algorithm = algorithm;
this.usages = usages;
}
@Override
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
for (String usage : usages) {
String v = null;
if (usage.compareToIgnoreCase("TLSServer") == 0) {
v = Validator.VAR_TLS_SERVER;
} else if (usage.compareToIgnoreCase("TLSClient") == 0) {
v = Validator.VAR_TLS_CLIENT;
} else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
v = Validator.VAR_PLUGIN_CODE_SIGNING;
}
if (debug != null) {
debug.println("Checking if usage constraint \"" + v +
"\" matches \"" + cp.getVariant() + "\"");
if (Debug.isVerbose()) {
// Because usage checking can come from many places
// a stack trace is very helpful.
(new Exception()).printStackTrace(debug.getPrintStream());
}
}
if (cp.getVariant().compareTo(v) == 0) {
if (next(cp)) {
return;
}
throw new CertPathValidatorException("Usage constraint " +
usage + " check failed: " + algorithm +
extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
}
/*
* This class contains constraints dealing with the key size
* support limits per algorithm. e.g. "keySize <= 1024"
*/
private static class KeySizeConstraint extends Constraint {
private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes
public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
switch (operator) {
case EQ: // an unavailable key size
this.minSize = 0;
this.maxSize = Integer.MAX_VALUE;
prohibitedSize = length;
break;
case NE:
this.minSize = length;
this.maxSize = length;
break;
case LT:
this.minSize = length;
this.maxSize = Integer.MAX_VALUE;
break;
case LE:
this.minSize = length + 1;
this.maxSize = Integer.MAX_VALUE;
break;
case GT:
this.minSize = 0;
this.maxSize = length;
break;
case GE:
this.minSize = 0;
this.maxSize = length > 1 ? (length - 1) : 0;
break;
default:
// unlikely to happen
this.minSize = Integer.MAX_VALUE;
this.maxSize = -1;
}
}
/*
* If we are passed a certificate, extract the public key and use it.
*
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
@Override
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
Key key = null;
if (cp.getPublicKey() != null) {
key = cp.getPublicKey();
} else if (cp.getCertificate() != null) {
key = cp.getCertificate().getPublicKey();
}
if (key != null && !permitsImpl(key)) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize limits. " +
algorithm + " " + KeyUtil.getKeySize(key) + "bit key" +
extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
// Check if key constraint disable the specified key
// Uses old style permit()
@Override
public boolean permits(Key key) {
// If we recursively find a constraint that permits us to use
// this key, return true and skip any other constraint checks.
if (nextConstraint != null && nextConstraint.permits(key)) {
return true;
}
if (debug != null) {
debug.println("KeySizeConstraints.permits(): " + algorithm);
}
return permitsImpl(key);
}
@Override
public boolean permits(AlgorithmParameters parameters) {
String paramAlg = parameters.getAlgorithm();
if (!algorithm.equalsIgnoreCase(parameters.getAlgorithm())) {
// Consider the impact of the algorithm aliases.
Collection<String> aliases =
AlgorithmDecomposer.getAliases(algorithm);
if (!aliases.contains(paramAlg)) {
return true;
}
}
int keySize = KeyUtil.getKeySize(parameters);
if (keySize == 0) {
return false;
} else if (keySize > 0) {
return !((keySize < minSize) || (keySize > maxSize) ||
(prohibitedSize == keySize));
} // Otherwise, the key size is not accessible or determined.
// Conservatively, please don't disable such keys.
return true;
}
private boolean permitsImpl(Key key) {
// Verify this constraint is for this public key algorithm
if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
return true;
}
int size = KeyUtil.getKeySize(key);
if (size == 0) {
return false; // we don't allow any key of size 0.
} else if (size > 0) {
return !((size < minSize) || (size > maxSize) ||
(prohibitedSize == size));
} // Otherwise, the key size is not accessible. Conservatively,
// please don't disable such keys.
return true;
}
}
/*
* This constraint is used for the complete disabling of the algorithm.
*/
private static class DisabledConstraint extends Constraint {
DisabledConstraint(String algo) {
algorithm = algo;
}
@Override
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled " +
"algorithm: " + algorithm + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
@Override
public boolean permits(Key key) {
return false;
}
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2012, 2013, 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.security.spec.AlgorithmParameterSpec;
import sun.security.util.ObjectIdentifier;
/**
* This immutable class is used when randomly generating a key pair and the
* consumer only specifies the length of the key and therefore a curve for that
* key size must be picked from a the list of supported curves using this spec.
*
* @see AlgorithmParameterSpec
* @see ECGenParameterSpec
*/
public class ECKeySizeParameterSpec implements AlgorithmParameterSpec {
private int keySize;
/**
* Creates a parameter specification for EC curve
* generation using a standard (or predefined) key size
* <code>keySize</code> in order to generate the corresponding
* (precomputed) elliptic curve.
* <p>
* Note, if the curve of the specified length is not supported,
* <code>AlgorithmParameters.init</code> will throw an exception.
*
* @param keySize the key size of the curve to lookup
*/
public ECKeySizeParameterSpec(int keySize) {
this.keySize = keySize;
}
/**
* Returns the key size of this spec.
*
* @return the standard or predefined key size.
*/
public int getKeySize() {
return keySize;
}
}

View file

@ -0,0 +1,236 @@
/*
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.IOException;
import java.security.*;
import java.security.spec.*;
/**
* This class implements encoding and decoding of Elliptic Curve parameters
* as specified in RFC 3279.
*
* However, only named curves are currently supported.
*
* ASN.1 from RFC 3279 follows. Note that X9.62 (2005) has added some additional
* options.
*
* <pre>
* EcpkParameters ::= CHOICE {
* ecParameters ECParameters,
* namedCurve OBJECT IDENTIFIER,
* implicitlyCA NULL }
*
* ECParameters ::= SEQUENCE {
* version ECPVer, -- version is always 1
* fieldID FieldID, -- identifies the finite field over
* -- which the curve is defined
* curve Curve, -- coefficients a and b of the
* -- elliptic curve
* base ECPoint, -- specifies the base point P
* -- on the elliptic curve
* order INTEGER, -- the order n of the base point
* cofactor INTEGER OPTIONAL -- The integer h = #E(Fq)/n
* }
*
* ECPVer ::= INTEGER {ecpVer1(1)}
*
* Curve ::= SEQUENCE {
* a FieldElement,
* b FieldElement,
* seed BIT STRING OPTIONAL }
*
* FieldElement ::= OCTET STRING
*
* ECPoint ::= OCTET STRING
* </pre>
*
* @since 1.6
* @author Andreas Sterbenz
*/
public final class ECParameters extends AlgorithmParametersSpi {
// used by ECPublicKeyImpl and ECPrivateKeyImpl
public static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)
throws InvalidKeyException {
try {
AlgorithmParameters params =
AlgorithmParameters.getInstance("EC", "SunEC");
params.init(spec);
return params;
} catch (GeneralSecurityException e) {
throw new InvalidKeyException("EC parameters error", e);
}
}
/*
* The parameters these AlgorithmParameters object represents.
* Currently, it is always an instance of NamedCurve.
*/
private NamedCurve namedCurve;
// A public constructor is required by AlgorithmParameters class.
public ECParameters() {
// empty
}
// AlgorithmParameterSpi methods
protected void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException {
if (paramSpec == null) {
throw new InvalidParameterSpecException
("paramSpec must not be null");
}
if (paramSpec instanceof NamedCurve) {
namedCurve = (NamedCurve)paramSpec;
return;
}
if (paramSpec instanceof ECParameterSpec) {
namedCurve = CurveDB.lookup((ECParameterSpec)paramSpec);
} else if (paramSpec instanceof ECGenParameterSpec) {
String name = ((ECGenParameterSpec)paramSpec).getName();
namedCurve = CurveDB.lookup(name);
} else if (paramSpec instanceof ECKeySizeParameterSpec) {
int keySize = ((ECKeySizeParameterSpec)paramSpec).getKeySize();
namedCurve = CurveDB.lookup(keySize);
} else {
throw new InvalidParameterSpecException
("Only ECParameterSpec and ECGenParameterSpec supported");
}
if (namedCurve == null) {
throw new InvalidParameterSpecException(
"Not a supported curve: " + paramSpec);
}
}
protected void engineInit(byte[] params) throws IOException {
DerValue encodedParams = new DerValue(params);
if (encodedParams.tag == DerValue.tag_ObjectId) {
ObjectIdentifier oid = encodedParams.getOID();
NamedCurve spec = CurveDB.lookup(oid.toString());
if (spec == null) {
throw new IOException("Unknown named curve: " + oid);
}
namedCurve = spec;
return;
}
throw new IOException("Only named ECParameters supported");
// The code below is incomplete.
// It is left as a starting point for a complete parsing implementation.
/*
if (encodedParams.tag != DerValue.tag_Sequence) {
throw new IOException("Unsupported EC parameters, tag: " +
encodedParams.tag);
}
encodedParams.data.reset();
DerInputStream in = encodedParams.data;
int version = in.getInteger();
if (version != 1) {
throw new IOException("Unsupported EC parameters version: " +
version);
}
ECField field = parseField(in);
EllipticCurve curve = parseCurve(in, field);
ECPoint point = parsePoint(in, curve);
BigInteger order = in.getBigInteger();
int cofactor = 0;
if (in.available() != 0) {
cofactor = in.getInteger();
}
// XXX HashAlgorithm optional
if (encodedParams.data.available() != 0) {
throw new IOException("encoded params have " +
encodedParams.data.available() +
" extra bytes");
}
return new ECParameterSpec(curve, point, order, cofactor);
*/
}
protected void engineInit(byte[] params, String decodingMethod)
throws IOException {
engineInit(params);
}
protected <T extends AlgorithmParameterSpec> T
engineGetParameterSpec(Class<T> spec)
throws InvalidParameterSpecException {
if (spec.isAssignableFrom(ECParameterSpec.class)) {
return spec.cast(namedCurve);
}
if (spec.isAssignableFrom(ECGenParameterSpec.class)) {
// Ensure the name is the Object ID
String name = namedCurve.getObjectId();
return spec.cast(new ECGenParameterSpec(name));
}
if (spec.isAssignableFrom(ECKeySizeParameterSpec.class)) {
int keySize = namedCurve.getCurve().getField().getFieldSize();
return spec.cast(new ECKeySizeParameterSpec(keySize));
}
throw new InvalidParameterSpecException(
"Only ECParameterSpec and ECGenParameterSpec supported");
}
protected byte[] engineGetEncoded() throws IOException {
return namedCurve.getEncoded();
}
protected byte[] engineGetEncoded(String encodingMethod)
throws IOException {
return engineGetEncoded();
}
protected String engineToString() {
if (namedCurve == null) {
return "Not initialized";
}
return namedCurve.toString();
}
}

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2006, 2013, 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.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import java.util.Arrays;
import sun.security.x509.X509Key;
public class ECUtil {
// Used by SunPKCS11 and SunJSSE.
public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
throws IOException {
if ((data.length == 0) || (data[0] != 4)) {
throw new IOException("Only uncompressed point format supported");
}
// Per ANSI X9.62, an encoded point is a 1 byte type followed by
// ceiling(log base 2 field-size / 8) bytes of x and the same of y.
int n = (data.length - 1) / 2;
if (n != ((curve.getField().getFieldSize() + 7 ) >> 3)) {
throw new IOException("Point does not match field size");
}
byte[] xb = Arrays.copyOfRange(data, 1, 1 + n);
byte[] yb = Arrays.copyOfRange(data, n + 1, n + 1 + n);
return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
}
// Used by SunPKCS11 and SunJSSE.
public static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
// get field size in bytes (rounding up)
int n = (curve.getField().getFieldSize() + 7) >> 3;
byte[] xb = trimZeroes(point.getAffineX().toByteArray());
byte[] yb = trimZeroes(point.getAffineY().toByteArray());
if ((xb.length > n) || (yb.length > n)) {
throw new RuntimeException
("Point coordinates do not match field size");
}
byte[] b = new byte[1 + (n << 1)];
b[0] = 4; // uncompressed
System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
return b;
}
public static byte[] trimZeroes(byte[] b) {
int i = 0;
while ((i < b.length - 1) && (b[i] == 0)) {
i++;
}
if (i == 0) {
return b;
}
return Arrays.copyOfRange(b, i, b.length);
}
private static KeyFactory getKeyFactory() {
try {
return KeyFactory.getInstance("EC", "SunEC");
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new RuntimeException(e);
}
}
public static ECPublicKey decodeX509ECPublicKey(byte[] encoded)
throws InvalidKeySpecException {
KeyFactory keyFactory = getKeyFactory();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
return (ECPublicKey)keyFactory.generatePublic(keySpec);
}
public static byte[] x509EncodeECPublicKey(ECPoint w,
ECParameterSpec params) throws InvalidKeySpecException {
KeyFactory keyFactory = getKeyFactory();
ECPublicKeySpec keySpec = new ECPublicKeySpec(w, params);
X509Key key = (X509Key)keyFactory.generatePublic(keySpec);
return key.getEncoded();
}
public static ECPrivateKey decodePKCS8ECPrivateKey(byte[] encoded)
throws InvalidKeySpecException {
KeyFactory keyFactory = getKeyFactory();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return (ECPrivateKey)keyFactory.generatePrivate(keySpec);
}
public static ECPrivateKey generateECPrivateKey(BigInteger s,
ECParameterSpec params) throws InvalidKeySpecException {
KeyFactory keyFactory = getKeyFactory();
ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, params);
return (ECPrivateKey)keyFactory.generatePrivate(keySpec);
}
public static AlgorithmParameters getECParameters(Provider p) {
try {
if (p != null) {
return AlgorithmParameters.getInstance("EC", p);
}
return AlgorithmParameters.getInstance("EC");
} catch (NoSuchAlgorithmException nsae) {
throw new RuntimeException(nsae);
}
}
public static byte[] encodeECParameterSpec(Provider p,
ECParameterSpec spec) {
AlgorithmParameters parameters = getECParameters(p);
try {
parameters.init(spec);
} catch (InvalidParameterSpecException ipse) {
throw new RuntimeException("Not a known named curve: " + spec);
}
try {
return parameters.getEncoded();
} catch (IOException ioe) {
// it is a bug if this should happen
throw new RuntimeException(ioe);
}
}
public static ECParameterSpec getECParameterSpec(Provider p,
ECParameterSpec spec) {
AlgorithmParameters parameters = getECParameters(p);
try {
parameters.init(spec);
return parameters.getParameterSpec(ECParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
return null;
}
}
public static ECParameterSpec getECParameterSpec(Provider p,
byte[] params)
throws IOException {
AlgorithmParameters parameters = getECParameters(p);
parameters.init(params);
try {
return parameters.getParameterSpec(ECParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
return null;
}
}
public static ECParameterSpec getECParameterSpec(Provider p, String name) {
AlgorithmParameters parameters = getECParameters(p);
try {
parameters.init(new ECGenParameterSpec(name));
return parameters.getParameterSpec(ECParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
return null;
}
}
public static ECParameterSpec getECParameterSpec(Provider p, int keySize) {
AlgorithmParameters parameters = getECParameters(p);
try {
parameters.init(new ECKeySizeParameterSpec(keySize));
return parameters.getParameterSpec(ECParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
return null;
}
}
public static String getCurveName(Provider p, ECParameterSpec spec) {
ECGenParameterSpec nameSpec;
AlgorithmParameters parameters = getECParameters(p);
try {
parameters.init(spec);
nameSpec = parameters.getParameterSpec(ECGenParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
return null;
}
if (nameSpec == null) {
return null;
}
return nameSpec.getName();
}
private ECUtil() {}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import sun.security.action.GetPropertyAction;
import java.io.FilePermission;
import java.security.Permission;
import jdk.internal.misc.SharedSecrets;
/**
* Take care of FilePermission compatibility after JDK-8164705.
*/
public class FilePermCompat {
/**
* New behavior? Keep compatibility? Both default true.
*/
public static final boolean nb;
public static final boolean compat;
static {
String flag = GetPropertyAction.privilegedGetProperty(
"jdk.io.permissionsUseCanonicalPath", "false");
switch (flag) {
case "true":
nb = false;
compat = false;
break;
case "false":
nb = true;
compat = true;
break;
default:
throw new RuntimeException(
"Invalid jdk.io.permissionsUseCanonicalPath: " + flag);
}
}
public static Permission newPermPlusAltPath(Permission input) {
if (compat && input instanceof FilePermission) {
return SharedSecrets.getJavaIOFilePermissionAccess()
.newPermPlusAltPath((FilePermission) input);
}
return input;
}
public static Permission newPermUsingAltPath(Permission input) {
if (input instanceof FilePermission) {
return SharedSecrets.getJavaIOFilePermissionAccess()
.newPermUsingAltPath((FilePermission) input);
}
return null;
}
}

View file

@ -0,0 +1,331 @@
/*
* Copyright (c) 1995, 2015, 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* This class encodes a buffer into the classic: "Hexadecimal Dump" format of
* the past. It is useful for analyzing the contents of binary buffers.
* The format produced is as follows:
* <pre>
* xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................
* </pre>
* Where xxxx is the offset into the buffer in 16 byte chunks, followed
* by ascii coded hexadecimal bytes followed by the ASCII representation of
* the bytes or '.' if they are not valid bytes.
*
* @author Chuck McManis
*/
public class HexDumpEncoder {
private int offset;
private int thisLineLength;
private int currentByte;
private byte thisLine[] = new byte[16];
static void hexDigit(PrintStream p, byte x) {
char c;
c = (char) ((x >> 4) & 0xf);
if (c > 9)
c = (char) ((c-10) + 'A');
else
c = (char)(c + '0');
p.write(c);
c = (char) (x & 0xf);
if (c > 9)
c = (char)((c-10) + 'A');
else
c = (char)(c + '0');
p.write(c);
}
protected int bytesPerAtom() {
return (1);
}
protected int bytesPerLine() {
return (16);
}
protected void encodeBufferPrefix(OutputStream o) throws IOException {
offset = 0;
pStream = new PrintStream(o);
}
protected void encodeLinePrefix(OutputStream o, int len) throws IOException {
hexDigit(pStream, (byte)((offset >>> 8) & 0xff));
hexDigit(pStream, (byte)(offset & 0xff));
pStream.print(": ");
currentByte = 0;
thisLineLength = len;
}
protected void encodeAtom(OutputStream o, byte buf[], int off, int len) throws IOException {
thisLine[currentByte] = buf[off];
hexDigit(pStream, buf[off]);
pStream.print(" ");
currentByte++;
if (currentByte == 8)
pStream.print(" ");
}
protected void encodeLineSuffix(OutputStream o) throws IOException {
if (thisLineLength < 16) {
for (int i = thisLineLength; i < 16; i++) {
pStream.print(" ");
if (i == 7)
pStream.print(" ");
}
}
pStream.print(" ");
for (int i = 0; i < thisLineLength; i++) {
if ((thisLine[i] < ' ') || (thisLine[i] > 'z')) {
pStream.print(".");
} else {
pStream.write(thisLine[i]);
}
}
pStream.println();
offset += thisLineLength;
}
/** Stream that understands "printing" */
protected PrintStream pStream;
/**
* This method works around the bizarre semantics of BufferedInputStream's
* read method.
*/
protected int readFully(InputStream in, byte buffer[])
throws java.io.IOException {
for (int i = 0; i < buffer.length; i++) {
int q = in.read();
if (q == -1)
return i;
buffer[i] = (byte)q;
}
return buffer.length;
}
/**
* Encode bytes from the input stream, and write them as text characters
* to the output stream. This method will run until it exhausts the
* input stream, but does not print the line suffix for a final
* line that is shorter than bytesPerLine().
*/
public void encode(InputStream inStream, OutputStream outStream)
throws IOException
{
int j;
int numBytes;
byte tmpbuffer[] = new byte[bytesPerLine()];
encodeBufferPrefix(outStream);
while (true) {
numBytes = readFully(inStream, tmpbuffer);
if (numBytes == 0) {
break;
}
encodeLinePrefix(outStream, numBytes);
for (j = 0; j < numBytes; j += bytesPerAtom()) {
if ((j + bytesPerAtom()) <= numBytes) {
encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
} else {
encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
}
}
if (numBytes < bytesPerLine()) {
break;
} else {
encodeLineSuffix(outStream);
}
}
}
/**
* A 'streamless' version of encode that simply takes a buffer of
* bytes and returns a string containing the encoded buffer.
*/
public String encode(byte aBuffer[]) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
String retVal = null;
try {
encode(inStream, outStream);
// explicit ascii->unicode conversion
retVal = outStream.toString("ISO-8859-1");
} catch (Exception IOException) {
// This should never happen.
throw new Error("CharacterEncoder.encode internal error");
}
return (retVal);
}
/**
* Return a byte array from the remaining bytes in this ByteBuffer.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
* <P>
* To avoid an extra copy, the implementation will attempt to return the
* byte array backing the ByteBuffer. If this is not possible, a
* new byte array will be created.
*/
private byte [] getBytes(ByteBuffer bb) {
/*
* This should never return a BufferOverflowException, as we're
* careful to allocate just the right amount.
*/
byte [] buf = null;
/*
* If it has a usable backing byte buffer, use it. Use only
* if the array exactly represents the current ByteBuffer.
*/
if (bb.hasArray()) {
byte [] tmp = bb.array();
if ((tmp.length == bb.capacity()) &&
(tmp.length == bb.remaining())) {
buf = tmp;
bb.position(bb.limit());
}
}
if (buf == null) {
/*
* This class doesn't have a concept of encode(buf, len, off),
* so if we have a partial buffer, we must reallocate
* space.
*/
buf = new byte[bb.remaining()];
/*
* position() automatically updated
*/
bb.get(buf);
}
return buf;
}
/**
* A 'streamless' version of encode that simply takes a ByteBuffer
* and returns a string containing the encoded buffer.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
*/
public String encode(ByteBuffer aBuffer) {
byte [] buf = getBytes(aBuffer);
return encode(buf);
}
/**
* Encode bytes from the input stream, and write them as text characters
* to the output stream. This method will run until it exhausts the
* input stream. It differs from encode in that it will add the
* line at the end of a final line that is shorter than bytesPerLine().
*/
public void encodeBuffer(InputStream inStream, OutputStream outStream)
throws IOException
{
int j;
int numBytes;
byte tmpbuffer[] = new byte[bytesPerLine()];
encodeBufferPrefix(outStream);
while (true) {
numBytes = readFully(inStream, tmpbuffer);
if (numBytes == 0) {
break;
}
encodeLinePrefix(outStream, numBytes);
for (j = 0; j < numBytes; j += bytesPerAtom()) {
if ((j + bytesPerAtom()) <= numBytes) {
encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
} else {
encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
}
}
encodeLineSuffix(outStream);
if (numBytes < bytesPerLine()) {
break;
}
}
}
/**
* Encode the buffer in <i>aBuffer</i> and write the encoded
* result to the OutputStream <i>aStream</i>.
*/
public void encodeBuffer(byte aBuffer[], OutputStream aStream)
throws IOException
{
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
encodeBuffer(inStream, aStream);
}
/**
* A 'streamless' version of encode that simply takes a buffer of
* bytes and returns a string containing the encoded buffer.
*/
public String encodeBuffer(byte aBuffer[]) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
try {
encodeBuffer(inStream, outStream);
} catch (Exception IOException) {
// This should never happen.
throw new Error("CharacterEncoder.encodeBuffer internal error");
}
return (outStream.toString());
}
/**
* Encode the <i>aBuffer</i> ByteBuffer and write the encoded
* result to the OutputStream <i>aStream</i>.
* <P>
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
*/
public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
throws IOException
{
byte [] buf = getBytes(aBuffer);
encodeBuffer(buf, aStream);
}
}

View file

@ -0,0 +1,467 @@
/*
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import java.security.cert.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import javax.net.ssl.SNIHostName;
import sun.net.util.IPAddressUtil;
import sun.security.ssl.ClientKeyExchangeService;
import sun.security.ssl.Debug;
import sun.security.x509.X500Name;
/**
* Class to check hostnames against the names specified in a certificate as
* required for TLS and LDAP.
*
*/
public class HostnameChecker {
// Constant for a HostnameChecker for TLS
public static final byte TYPE_TLS = 1;
private static final HostnameChecker INSTANCE_TLS =
new HostnameChecker(TYPE_TLS);
// Constant for a HostnameChecker for LDAP
public static final byte TYPE_LDAP = 2;
private static final HostnameChecker INSTANCE_LDAP =
new HostnameChecker(TYPE_LDAP);
// constants for subject alt names of type DNS and IP
private static final int ALTNAME_DNS = 2;
private static final int ALTNAME_IP = 7;
private static final Debug debug = Debug.getInstance("ssl");
// the algorithm to follow to perform the check. Currently unused.
private final byte checkType;
private HostnameChecker(byte checkType) {
this.checkType = checkType;
}
/**
* Get a HostnameChecker instance. checkType should be one of the
* TYPE_* constants defined in this class.
*/
public static HostnameChecker getInstance(byte checkType) {
if (checkType == TYPE_TLS) {
return INSTANCE_TLS;
} else if (checkType == TYPE_LDAP) {
return INSTANCE_LDAP;
}
throw new IllegalArgumentException("Unknown check type: " + checkType);
}
/**
* Perform the check.
*
* @param expectedName the expected host name or ip address
* @param cert the certificate to check against
* @param chainsToPublicCA true if the certificate chains to a public
* root CA (as pre-installed in the cacerts file)
* @throws CertificateException if the name does not match any of
* the names specified in the certificate
*/
public void match(String expectedName, X509Certificate cert,
boolean chainsToPublicCA) throws CertificateException {
if (isIpAddress(expectedName)) {
matchIP(expectedName, cert);
} else {
matchDNS(expectedName, cert, chainsToPublicCA);
}
}
public void match(String expectedName, X509Certificate cert)
throws CertificateException {
match(expectedName, cert, false);
}
/**
* Perform the check for Kerberos.
*/
public static boolean match(String expectedName, Principal principal) {
String hostName = getServerName(principal);
return (expectedName.equalsIgnoreCase(hostName));
}
/**
* Return the Server name from Kerberos principal.
*/
public static String getServerName(Principal principal) {
ClientKeyExchangeService p =
ClientKeyExchangeService.find("KRB5");
if (p == null) {
throw new AssertionError("Kerberos should have been available");
}
return p.getServiceHostName(principal);
}
/**
* Test whether the given hostname looks like a literal IPv4 or IPv6
* address. The hostname does not need to be a fully qualified name.
*
* This is not a strict check that performs full input validation.
* That means if the method returns true, name need not be a correct
* IP address, rather that it does not represent a valid DNS hostname.
* Likewise for IP addresses when it returns false.
*/
private static boolean isIpAddress(String name) {
if (IPAddressUtil.isIPv4LiteralAddress(name) ||
IPAddressUtil.isIPv6LiteralAddress(name)) {
return true;
} else {
return false;
}
}
/**
* Check if the certificate allows use of the given IP address.
*
* From RFC2818:
* In some cases, the URI is specified as an IP address rather than a
* hostname. In this case, the iPAddress subjectAltName must be present
* in the certificate and must exactly match the IP in the URI.
*/
private static void matchIP(String expectedIP, X509Certificate cert)
throws CertificateException {
Collection<List<?>> subjAltNames = cert.getSubjectAlternativeNames();
if (subjAltNames == null) {
throw new CertificateException
("No subject alternative names present");
}
for (List<?> next : subjAltNames) {
// For IP address, it needs to be exact match
if (((Integer)next.get(0)).intValue() == ALTNAME_IP) {
String ipAddress = (String)next.get(1);
if (expectedIP.equalsIgnoreCase(ipAddress)) {
return;
} else {
// compare InetAddress objects in order to ensure
// equality between a long IPv6 address and its
// abbreviated form.
try {
if (InetAddress.getByName(expectedIP).equals(
InetAddress.getByName(ipAddress))) {
return;
}
} catch (UnknownHostException e) {
} catch (SecurityException e) {}
}
}
}
throw new CertificateException("No subject alternative " +
"names matching " + "IP address " +
expectedIP + " found");
}
/**
* Check if the certificate allows use of the given DNS name.
*
* From RFC2818:
* If a subjectAltName extension of type dNSName is present, that MUST
* be used as the identity. Otherwise, the (most specific) Common Name
* field in the Subject field of the certificate MUST be used. Although
* the use of the Common Name is existing practice, it is deprecated and
* Certification Authorities are encouraged to use the dNSName instead.
*
* Matching is performed using the matching rules specified by
* [RFC5280]. If more than one identity of a given type is present in
* the certificate (e.g., more than one dNSName name, a match in any one
* of the set is considered acceptable.)
*/
private void matchDNS(String expectedName, X509Certificate cert,
boolean chainsToPublicCA)
throws CertificateException {
// Check that the expected name is a valid domain name.
try {
// Using the checking implemented in SNIHostName
SNIHostName sni = new SNIHostName(expectedName);
} catch (IllegalArgumentException iae) {
throw new CertificateException(
"Illegal given domain name: " + expectedName, iae);
}
Collection<List<?>> subjAltNames = cert.getSubjectAlternativeNames();
if (subjAltNames != null) {
boolean foundDNS = false;
for (List<?> next : subjAltNames) {
if (((Integer)next.get(0)).intValue() == ALTNAME_DNS) {
foundDNS = true;
String dnsName = (String)next.get(1);
if (isMatched(expectedName, dnsName, chainsToPublicCA)) {
return;
}
}
}
if (foundDNS) {
// if certificate contains any subject alt names of type DNS
// but none match, reject
throw new CertificateException("No subject alternative DNS "
+ "name matching " + expectedName + " found.");
}
}
X500Name subjectName = getSubjectX500Name(cert);
DerValue derValue = subjectName.findMostSpecificAttribute
(X500Name.commonName_oid);
if (derValue != null) {
try {
if (isMatched(expectedName, derValue.getAsString(),
chainsToPublicCA)) {
return;
}
} catch (IOException e) {
// ignore
}
}
String msg = "No name matching " + expectedName + " found";
throw new CertificateException(msg);
}
/**
* Return the subject of a certificate as X500Name, by reparsing if
* necessary. X500Name should only be used if access to name components
* is required, in other cases X500Principal is to be preferred.
*
* This method is currently used from within JSSE, do not remove.
*/
public static X500Name getSubjectX500Name(X509Certificate cert)
throws CertificateParsingException {
try {
Principal subjectDN = cert.getSubjectDN();
if (subjectDN instanceof X500Name) {
return (X500Name)subjectDN;
} else {
X500Principal subjectX500 = cert.getSubjectX500Principal();
return new X500Name(subjectX500.getEncoded());
}
} catch (IOException e) {
throw(CertificateParsingException)
new CertificateParsingException().initCause(e);
}
}
/**
* Returns true if name matches against template.<p>
*
* The matching is performed as per RFC 2818 rules for TLS and
* RFC 2830 rules for LDAP.<p>
*
* The <code>name</code> parameter should represent a DNS name.
* The <code>template</code> parameter
* may contain the wildcard character *
*/
private boolean isMatched(String name, String template,
boolean chainsToPublicCA) {
if (hasIllegalWildcard(name, template, chainsToPublicCA)) {
return false;
}
// check the validity of the domain name template.
try {
// Replacing wildcard character '*' with 'x' so as to check
// the domain name template validity.
//
// Using the checking implemented in SNIHostName
SNIHostName sni = new SNIHostName(template.replace('*', 'x'));
} catch (IllegalArgumentException iae) {
// It would be nice to add debug log if not matching.
return false;
}
if (checkType == TYPE_TLS) {
return matchAllWildcards(name, template);
} else if (checkType == TYPE_LDAP) {
return matchLeftmostWildcard(name, template);
} else {
return false;
}
}
/**
* Returns true if the template contains an illegal wildcard character.
*/
private static boolean hasIllegalWildcard(String domain, String template,
boolean chainsToPublicCA) {
// not ok if it is a single wildcard character or "*."
if (template.equals("*") || template.equals("*.")) {
if (debug != null) {
debug.println("Certificate domain name has illegal single " +
"wildcard character: " + template);
}
return true;
}
int lastWildcardIndex = template.lastIndexOf("*");
// ok if it has no wildcard character
if (lastWildcardIndex == -1) {
return false;
}
String afterWildcard = template.substring(lastWildcardIndex);
int firstDotIndex = afterWildcard.indexOf(".");
// not ok if there is no dot after wildcard (ex: "*com")
if (firstDotIndex == -1) {
if (debug != null) {
debug.println("Certificate domain name has illegal wildcard, " +
"no dot after wildcard character: " + template);
}
return true;
}
// If the wildcarded domain is a top-level domain under which names
// can be registered, then a wildcard is not allowed.
if (!chainsToPublicCA) {
return false; // skip check for non-public certificates
}
Optional<RegisteredDomain> rd = RegisteredDomain.from(domain)
.filter(d -> d.type() == RegisteredDomain.Type.ICANN);
if (rd.isPresent()) {
String wDomain = afterWildcard.substring(firstDotIndex + 1);
if (rd.get().publicSuffix().equalsIgnoreCase(wDomain)) {
if (debug != null) {
debug.println("Certificate domain name has illegal " +
"wildcard for public suffix: " + template);
}
return true;
}
}
return false;
}
/**
* Returns true if name matches against template.<p>
*
* According to RFC 2818, section 3.1 -
* Names may contain the wildcard character * which is
* considered to match any single domain name component
* or component fragment.
* E.g., *.a.com matches foo.a.com but not
* bar.foo.a.com. f*.com matches foo.com but not bar.com.
*/
private static boolean matchAllWildcards(String name,
String template) {
name = name.toLowerCase(Locale.ENGLISH);
template = template.toLowerCase(Locale.ENGLISH);
StringTokenizer nameSt = new StringTokenizer(name, ".");
StringTokenizer templateSt = new StringTokenizer(template, ".");
if (nameSt.countTokens() != templateSt.countTokens()) {
return false;
}
while (nameSt.hasMoreTokens()) {
if (!matchWildCards(nameSt.nextToken(),
templateSt.nextToken())) {
return false;
}
}
return true;
}
/**
* Returns true if name matches against template.<p>
*
* As per RFC 2830, section 3.6 -
* The "*" wildcard character is allowed. If present, it applies only
* to the left-most name component.
* E.g. *.bar.com would match a.bar.com, b.bar.com, etc. but not
* bar.com.
*/
private static boolean matchLeftmostWildcard(String name,
String template) {
name = name.toLowerCase(Locale.ENGLISH);
template = template.toLowerCase(Locale.ENGLISH);
// Retrieve leftmost component
int templateIdx = template.indexOf(".");
int nameIdx = name.indexOf(".");
if (templateIdx == -1)
templateIdx = template.length();
if (nameIdx == -1)
nameIdx = name.length();
if (matchWildCards(name.substring(0, nameIdx),
template.substring(0, templateIdx))) {
// match rest of the name
return template.substring(templateIdx).equals(
name.substring(nameIdx));
} else {
return false;
}
}
/**
* Returns true if the name matches against the template that may
* contain wildcard char * <p>
*/
private static boolean matchWildCards(String name, String template) {
int wildcardIdx = template.indexOf("*");
if (wildcardIdx == -1)
return name.equals(template);
boolean isBeginning = true;
String beforeWildcard = "";
String afterWildcard = template;
while (wildcardIdx != -1) {
// match in sequence the non-wildcard chars in the template.
beforeWildcard = afterWildcard.substring(0, wildcardIdx);
afterWildcard = afterWildcard.substring(wildcardIdx + 1);
int beforeStartIdx = name.indexOf(beforeWildcard);
if ((beforeStartIdx == -1) ||
(isBeginning && beforeStartIdx != 0)) {
return false;
}
isBeginning = false;
// update the match scope
name = name.substring(beforeStartIdx + beforeWildcard.length());
wildcardIdx = afterWildcard.indexOf("*");
}
return name.endsWith(afterWildcard);
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2009, 2017 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* IOUtils: A collection of IO-related public static methods.
*/
package sun.security.util;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class IOUtils {
/**
* Read up to <code>length</code> of bytes from <code>in</code>
* until EOF is detected.
* @param is input stream, must not be null
* @param length number of bytes to read
* @param readAll if true, an EOFException will be thrown if not enough
* bytes are read.
* @return bytes read
* @throws IOException Any IO error or a premature EOF is detected
*/
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
if (length < 0) {
throw new IOException("Invalid length");
}
byte[] output = {};
int pos = 0;
while (pos < length) {
int bytesToRead;
if (pos >= output.length) { // Only expand when there's no room
bytesToRead = Math.min(length - pos, output.length + 1024);
if (output.length < pos + bytesToRead) {
output = Arrays.copyOf(output, pos + bytesToRead);
}
} else {
bytesToRead = output.length - pos;
}
int cc = is.read(output, pos, bytesToRead);
if (cc < 0) {
if (readAll) {
throw new EOFException("Detect premature EOF");
} else {
if (output.length != pos) {
output = Arrays.copyOf(output, pos);
}
break;
}
}
pos += cc;
}
return output;
}
}

View file

@ -0,0 +1,311 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.*;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateException;
import java.util.*;
import sun.security.util.Debug;
/**
* This class delegates to a primary or secondary keystore implementation.
*
* @since 9
*/
public class KeyStoreDelegator extends KeyStoreSpi {
private static final String KEYSTORE_TYPE_COMPAT = "keystore.type.compat";
private static final Debug debug = Debug.getInstance("keystore");
private String primaryType; // the primary keystore's type
private String secondaryType; // the secondary keystore's type
private Class<? extends KeyStoreSpi> primaryKeyStore;
// the primary keystore's class
private Class<? extends KeyStoreSpi> secondaryKeyStore;
// the secondary keystore's class
private String type; // the delegate's type
private KeyStoreSpi keystore; // the delegate
private boolean compatModeEnabled = true;
public KeyStoreDelegator(
String primaryType,
Class<? extends KeyStoreSpi> primaryKeyStore,
String secondaryType,
Class<? extends KeyStoreSpi> secondaryKeyStore) {
// Check whether compatibility mode has been disabled
compatModeEnabled = "true".equalsIgnoreCase(
AccessController.doPrivileged((PrivilegedAction<String>) () ->
Security.getProperty(KEYSTORE_TYPE_COMPAT)));
if (compatModeEnabled) {
this.primaryType = primaryType;
this.secondaryType = secondaryType;
this.primaryKeyStore = primaryKeyStore;
this.secondaryKeyStore = secondaryKeyStore;
} else {
this.primaryType = primaryType;
this.secondaryType = null;
this.primaryKeyStore = primaryKeyStore;
this.secondaryKeyStore = null;
if (debug != null) {
debug.println("WARNING: compatibility mode disabled for " +
primaryType + " and " + secondaryType + " keystore types");
}
}
}
@Override
public Key engineGetKey(String alias, char[] password)
throws NoSuchAlgorithmException, UnrecoverableKeyException {
return keystore.engineGetKey(alias, password);
}
@Override
public Certificate[] engineGetCertificateChain(String alias) {
return keystore.engineGetCertificateChain(alias);
}
@Override
public Certificate engineGetCertificate(String alias) {
return keystore.engineGetCertificate(alias);
}
@Override
public Date engineGetCreationDate(String alias) {
return keystore.engineGetCreationDate(alias);
}
@Override
public void engineSetKeyEntry(String alias, Key key, char[] password,
Certificate[] chain) throws KeyStoreException {
keystore.engineSetKeyEntry(alias, key, password, chain);
}
@Override
public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
throws KeyStoreException {
keystore.engineSetKeyEntry(alias, key, chain);
}
@Override
public void engineSetCertificateEntry(String alias, Certificate cert)
throws KeyStoreException {
keystore.engineSetCertificateEntry(alias, cert);
}
@Override
public void engineDeleteEntry(String alias) throws KeyStoreException {
keystore.engineDeleteEntry(alias);
}
@Override
public Enumeration<String> engineAliases() {
return keystore.engineAliases();
}
@Override
public boolean engineContainsAlias(String alias) {
return keystore.engineContainsAlias(alias);
}
@Override
public int engineSize() {
return keystore.engineSize();
}
@Override
public boolean engineIsKeyEntry(String alias) {
return keystore.engineIsKeyEntry(alias);
}
@Override
public boolean engineIsCertificateEntry(String alias) {
return keystore.engineIsCertificateEntry(alias);
}
@Override
public String engineGetCertificateAlias(Certificate cert) {
return keystore.engineGetCertificateAlias(cert);
}
@Override
public KeyStore.Entry engineGetEntry(String alias,
KeyStore.ProtectionParameter protParam)
throws KeyStoreException, NoSuchAlgorithmException,
UnrecoverableEntryException {
return keystore.engineGetEntry(alias, protParam);
}
@Override
public void engineSetEntry(String alias, KeyStore.Entry entry,
KeyStore.ProtectionParameter protParam)
throws KeyStoreException {
keystore.engineSetEntry(alias, entry, protParam);
}
@Override
public boolean engineEntryInstanceOf(String alias,
Class<? extends KeyStore.Entry> entryClass) {
return keystore.engineEntryInstanceOf(alias, entryClass);
}
@Override
public void engineStore(OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException {
if (debug != null) {
debug.println("Storing keystore in " + type + " format");
}
keystore.engineStore(stream, password);
}
@Override
public void engineLoad(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException {
// A new keystore is always created in the primary keystore format
if (stream == null) {
try {
@SuppressWarnings("deprecation")
KeyStoreSpi tmp = primaryKeyStore.newInstance();
keystore = tmp;
} catch (InstantiationException | IllegalAccessException e) {
// can safely ignore
}
type = primaryType;
if (debug != null) {
debug.println("Creating a new keystore in " + type + " format");
}
keystore.engineLoad(stream, password);
} else {
// First try the primary keystore then try the secondary keystore
InputStream bufferedStream = new BufferedInputStream(stream);
bufferedStream.mark(Integer.MAX_VALUE);
try {
@SuppressWarnings("deprecation")
KeyStoreSpi tmp = primaryKeyStore.newInstance();
keystore = tmp;
type = primaryType;
keystore.engineLoad(bufferedStream, password);
} catch (Exception e) {
// incorrect password
if (e instanceof IOException &&
e.getCause() instanceof UnrecoverableKeyException) {
throw (IOException)e;
}
try {
// Ignore secondary keystore when no compatibility mode
if (!compatModeEnabled) {
throw e;
}
@SuppressWarnings("deprecation")
KeyStoreSpi tmp= secondaryKeyStore.newInstance();
keystore = tmp;
type = secondaryType;
bufferedStream.reset();
keystore.engineLoad(bufferedStream, password);
if (debug != null) {
debug.println("WARNING: switching from " +
primaryType + " to " + secondaryType +
" keystore file format has altered the " +
"keystore security level");
}
} catch (InstantiationException |
IllegalAccessException e2) {
// can safely ignore
} catch (IOException |
NoSuchAlgorithmException |
CertificateException e3) {
// incorrect password
if (e3 instanceof IOException &&
e3.getCause() instanceof UnrecoverableKeyException) {
throw (IOException)e3;
}
// rethrow the outer exception
if (e instanceof IOException) {
throw (IOException)e;
} else if (e instanceof CertificateException) {
throw (CertificateException)e;
} else if (e instanceof NoSuchAlgorithmException) {
throw (NoSuchAlgorithmException)e;
}
}
}
if (debug != null) {
debug.println("Loaded a keystore in " + type + " format");
}
}
}
/**
* Probe the first few bytes of the keystore data stream for a valid
* keystore encoding. Only the primary keystore implementation is probed.
*/
@Override
public boolean engineProbe(InputStream stream) throws IOException {
boolean result = false;
try {
@SuppressWarnings("deprecation")
KeyStoreSpi tmp = primaryKeyStore.newInstance();
keystore = tmp;
type = primaryType;
result = keystore.engineProbe(stream);
} catch (Exception e) {
throw new IOException(e);
} finally {
// reset
if (result == false) {
type = null;
keystore = null;
}
}
return result;
}
}

View file

@ -0,0 +1,370 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;
import java.security.interfaces.DSAKey;
import java.security.interfaces.DSAParams;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPublicKeySpec;
import java.math.BigInteger;
import sun.security.jca.JCAUtil;
/**
* A utility class to get key length, valiate keys, etc.
*/
public final class KeyUtil {
/**
* Returns the key size of the given key object in bits.
*
* @param key the key object, cannot be null
* @return the key size of the given key object in bits, or -1 if the
* key size is not accessible
*/
public static final int getKeySize(Key key) {
int size = -1;
if (key instanceof Length) {
try {
Length ruler = (Length)key;
size = ruler.length();
} catch (UnsupportedOperationException usoe) {
// ignore the exception
}
if (size >= 0) {
return size;
}
}
// try to parse the length from key specification
if (key instanceof SecretKey) {
SecretKey sk = (SecretKey)key;
String format = sk.getFormat();
if ("RAW".equals(format) && sk.getEncoded() != null) {
size = (sk.getEncoded().length * 8);
} // Otherwise, it may be a unextractable key of PKCS#11, or
// a key we are not able to handle.
} else if (key instanceof RSAKey) {
RSAKey pubk = (RSAKey)key;
size = pubk.getModulus().bitLength();
} else if (key instanceof ECKey) {
ECKey pubk = (ECKey)key;
size = pubk.getParams().getOrder().bitLength();
} else if (key instanceof DSAKey) {
DSAKey pubk = (DSAKey)key;
DSAParams params = pubk.getParams(); // params can be null
size = (params != null) ? params.getP().bitLength() : -1;
} else if (key instanceof DHKey) {
DHKey pubk = (DHKey)key;
size = pubk.getParams().getP().bitLength();
} // Otherwise, it may be a unextractable key of PKCS#11, or
// a key we are not able to handle.
return size;
}
/**
* Returns the key size of the given cryptographic parameters in bits.
*
* @param parameters the cryptographic parameters, cannot be null
* @return the key size of the given cryptographic parameters in bits,
* or -1 if the key size is not accessible
*/
public static final int getKeySize(AlgorithmParameters parameters) {
String algorithm = parameters.getAlgorithm();
switch (algorithm) {
case "EC":
try {
ECKeySizeParameterSpec ps = parameters.getParameterSpec(
ECKeySizeParameterSpec.class);
if (ps != null) {
return ps.getKeySize();
}
} catch (InvalidParameterSpecException ipse) {
// ignore
}
try {
ECParameterSpec ps = parameters.getParameterSpec(
ECParameterSpec.class);
if (ps != null) {
return ps.getOrder().bitLength();
}
} catch (InvalidParameterSpecException ipse) {
// ignore
}
// Note: the ECGenParameterSpec case should be covered by the
// ECParameterSpec case above.
// See ECUtil.getECParameterSpec(Provider, String).
break;
case "DiffieHellman":
try {
DHParameterSpec ps = parameters.getParameterSpec(
DHParameterSpec.class);
if (ps != null) {
return ps.getP().bitLength();
}
} catch (InvalidParameterSpecException ipse) {
// ignore
}
break;
// May support more AlgorithmParameters algorithms in the future.
}
return -1;
}
/**
* Returns whether the key is valid or not.
* <P>
* Note that this method is only apply to DHPublicKey at present.
*
* @param key the key object, cannot be null
*
* @throws NullPointerException if {@code key} is null
* @throws InvalidKeyException if {@code key} is invalid
*/
public static final void validate(Key key)
throws InvalidKeyException {
if (key == null) {
throw new NullPointerException(
"The key to be validated cannot be null");
}
if (key instanceof DHPublicKey) {
validateDHPublicKey((DHPublicKey)key);
}
}
/**
* Returns whether the key spec is valid or not.
* <P>
* Note that this method is only apply to DHPublicKeySpec at present.
*
* @param keySpec
* the key spec object, cannot be null
*
* @throws NullPointerException if {@code keySpec} is null
* @throws InvalidKeyException if {@code keySpec} is invalid
*/
public static final void validate(KeySpec keySpec)
throws InvalidKeyException {
if (keySpec == null) {
throw new NullPointerException(
"The key spec to be validated cannot be null");
}
if (keySpec instanceof DHPublicKeySpec) {
validateDHPublicKey((DHPublicKeySpec)keySpec);
}
}
/**
* Returns whether the specified provider is Oracle provider or not.
*
* @param providerName
* the provider name
* @return true if, and only if, the provider of the specified
* {@code providerName} is Oracle provider
*/
public static final boolean isOracleJCEProvider(String providerName) {
return providerName != null &&
(providerName.equals("SunJCE") ||
providerName.equals("SunMSCAPI") ||
providerName.equals("OracleUcrypto") ||
providerName.startsWith("SunPKCS11"));
}
/**
* Check the format of TLS PreMasterSecret.
* <P>
* To avoid vulnerabilities described by section 7.4.7.1, RFC 5246,
* treating incorrectly formatted message blocks and/or mismatched
* version numbers in a manner indistinguishable from correctly
* formatted RSA blocks.
*
* RFC 5246 describes the approach as:
* <pre>{@literal
*
* 1. Generate a string R of 48 random bytes
*
* 2. Decrypt the message to recover the plaintext M
*
* 3. If the PKCS#1 padding is not correct, or the length of message
* M is not exactly 48 bytes:
* pre_master_secret = R
* else If ClientHello.client_version <= TLS 1.0, and version
* number check is explicitly disabled:
* premaster secret = M
* else If M[0..1] != ClientHello.client_version:
* premaster secret = R
* else:
* premaster secret = M
*
* Note that #2 should have completed before the call to this method.
* }</pre>
*
* @param clientVersion the version of the TLS protocol by which the
* client wishes to communicate during this session
* @param serverVersion the negotiated version of the TLS protocol which
* contains the lower of that suggested by the client in the client
* hello and the highest supported by the server.
* @param encoded the encoded key in its "RAW" encoding format
* @param isFailOver whether or not the previous decryption of the
* encrypted PreMasterSecret message run into problem
* @return the polished PreMasterSecret key in its "RAW" encoding format
*/
public static byte[] checkTlsPreMasterSecretKey(
int clientVersion, int serverVersion, SecureRandom random,
byte[] encoded, boolean isFailOver) {
if (random == null) {
random = JCAUtil.getSecureRandom();
}
byte[] replacer = new byte[48];
random.nextBytes(replacer);
if (!isFailOver && (encoded != null)) {
// check the length
if (encoded.length != 48) {
// private, don't need to clone the byte array.
return replacer;
}
int encodedVersion =
((encoded[0] & 0xFF) << 8) | (encoded[1] & 0xFF);
if (clientVersion != encodedVersion) {
if (clientVersion > 0x0301 || // 0x0301: TLSv1
serverVersion != encodedVersion) {
encoded = replacer;
} // Otherwise, For compatibility, we maintain the behavior
// that the version in pre_master_secret can be the
// negotiated version for TLS v1.0 and SSL v3.0.
}
// private, don't need to clone the byte array.
return encoded;
}
// private, don't need to clone the byte array.
return replacer;
}
/**
* Returns whether the Diffie-Hellman public key is valid or not.
*
* Per RFC 2631 and NIST SP800-56A, the following algorithm is used to
* validate Diffie-Hellman public keys:
* 1. Verify that y lies within the interval [2,p-1]. If it does not,
* the key is invalid.
* 2. Compute y^q mod p. If the result == 1, the key is valid.
* Otherwise the key is invalid.
*/
private static void validateDHPublicKey(DHPublicKey publicKey)
throws InvalidKeyException {
DHParameterSpec paramSpec = publicKey.getParams();
BigInteger p = paramSpec.getP();
BigInteger g = paramSpec.getG();
BigInteger y = publicKey.getY();
validateDHPublicKey(p, g, y);
}
private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec)
throws InvalidKeyException {
validateDHPublicKey(publicKeySpec.getP(),
publicKeySpec.getG(), publicKeySpec.getY());
}
private static void validateDHPublicKey(BigInteger p,
BigInteger g, BigInteger y) throws InvalidKeyException {
// For better interoperability, the interval is limited to [2, p-2].
BigInteger leftOpen = BigInteger.ONE;
BigInteger rightOpen = p.subtract(BigInteger.ONE);
if (y.compareTo(leftOpen) <= 0) {
throw new InvalidKeyException(
"Diffie-Hellman public key is too small");
}
if (y.compareTo(rightOpen) >= 0) {
throw new InvalidKeyException(
"Diffie-Hellman public key is too large");
}
// y^q mod p == 1?
// Unable to perform this check as q is unknown in this circumstance.
// p is expected to be prime. However, it is too expensive to check
// that p is prime. Instead, in order to mitigate the impact of
// non-prime values, we check that y is not a factor of p.
BigInteger r = p.remainder(y);
if (r.equals(BigInteger.ZERO)) {
throw new InvalidKeyException("Invalid Diffie-Hellman parameters");
}
}
/**
* Trim leading (most significant) zeroes from the result.
*
* @throws NullPointerException if {@code b} is null
*/
public static byte[] trimZeroes(byte[] b) {
int i = 0;
while ((i < b.length - 1) && (b[i] == 0)) {
i++;
}
if (i == 0) {
return b;
}
byte[] t = new byte[b.length - i];
System.arraycopy(b, i, t, 0, t.length);
return t;
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.AlgorithmParameters;
import java.security.CryptoPrimitive;
import java.security.Key;
import java.util.Set;
import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms;
/**
* Algorithm constraints for legacy algorithms.
*/
public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints {
// the known security property, jdk.tls.legacyAlgorithms
public static final String PROPERTY_TLS_LEGACY_ALGS =
"jdk.tls.legacyAlgorithms";
private final String[] legacyAlgorithms;
public LegacyAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
legacyAlgorithms = getAlgorithms(propertyName);
}
@Override
public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) {
return checkAlgorithm(legacyAlgorithms, algorithm, decomposer);
}
@Override
public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
return true;
}
@Override
public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) {
return checkAlgorithm(legacyAlgorithms, algorithm, decomposer);
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2012, 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;
/**
* The Length interface defines the length of an object
*/
public interface Length {
/**
* Gets the length of this object
* <p>
* Note that if a class of java.security.Key implements this interfaces,
* the length should be measured in bits.
*
* @return the length of this object
* @throws UnsupportedOperationException if the operation is not supported
*/
public int length();
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class produces formatted and localized messages describing security
* issues. Some messages may be required when the VM is not fully booted. In
* this case, localization resources and classes used for message formatting
* may not be available. When the VM is not booted, the message will not be
* localized, and it will be formatted using simplified message formatting
* code that is contained in this class.
*/
/*
* Some of this code is executed before the VM is fully booted. Some import
* statements have been omitted to help prevent accidental use of classes that
* may not be available during boot.
*/
public class LocalizedMessage {
private static final Resources resources = new Resources();
private final String key;
/**
* A LocalizedMessage can be instantiated with a key and formatted with
* arguments later in the style of MessageFormat. This organization
* allows the actual formatting (and associated permission checks) to be
* avoided unless the resulting string is needed.
* @param key
*/
public LocalizedMessage(String key) {
this.key = key;
}
/**
* Return a localized string corresponding to the key stored in this
* object, formatted with the provided arguments. When the VM is booted,
* this method will obtain the correct localized message and format it
* using java.text.MessageFormat. Otherwise, a non-localized string is
* returned, and the formatting is performed by simplified formatting code.
*
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public String format(Object... arguments) {
return getMessage(key, arguments);
}
/**
* Return a non-localized string corresponding to the provided key, and
* formatted with the provided arguments. All strings are obtained from
* sun.security.util.Resources, and the formatting only supports
* simple positional argument replacement (e.g. {1}).
*
* @param key The key of the desired string in Resources
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public static String getMessageUnbooted(String key,
Object... arguments) {
String value = resources.getString(key);
if (arguments == null || arguments.length == 0) {
return value;
}
// Classes like StringTokenizer may not be loaded, so parsing
// is performed with String methods
StringBuilder sb = new StringBuilder();
int nextBraceIndex;
while ((nextBraceIndex = value.indexOf('{')) >= 0) {
String firstPart = value.substring(0, nextBraceIndex);
sb.append(firstPart);
value = value.substring(nextBraceIndex + 1);
// look for closing brace and argument index
nextBraceIndex = value.indexOf('}');
if (nextBraceIndex < 0) {
// no closing brace
// MessageFormat would throw IllegalArgumentException, but
// that exception class may not be loaded yet
throw new RuntimeException("Unmatched braces");
}
String indexStr = value.substring(0, nextBraceIndex);
try {
int index = Integer.parseInt(indexStr);
sb.append(arguments[index]);
}
catch(NumberFormatException e) {
// argument index is not an integer
throw new RuntimeException("not an integer: " + indexStr);
}
value = value.substring(nextBraceIndex + 1);
}
sb.append(value);
return sb.toString();
}
/**
* Return a localized string corresponding to the provided key, and
* formatted with the provided arguments. When the VM is booted, this
* method will obtain the correct localized message and format it using
* java.text.MessageFormat. Otherwise, a non-localized string is returned,
* and the formatting is performed by simplified formatting code.
*
* @param key The key of the desired string in the security resource bundle
* @param arguments The arguments that should be placed in the message
* @return A formatted message string
*/
public static String getMessage(String key,
Object... arguments) {
if (jdk.internal.misc.VM.isBooted()) {
// Localization and formatting resources are available
String value = ResourcesMgr.getString(key);
if (arguments == null) {
return value;
}
java.text.MessageFormat form = new java.text.MessageFormat(value);
return form.format(arguments);
} else {
return getMessageUnbooted(key, arguments);
}
}
}

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 1997, 2011, 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.security.*;
import java.util.HashMap;
import java.io.ByteArrayOutputStream;
/**
* This class is used to compute digests on sections of the Manifest.
*/
public class ManifestDigester {
public static final String MF_MAIN_ATTRS = "Manifest-Main-Attributes";
/** the raw bytes of the manifest */
private byte[] rawBytes;
/** the offset/length pair for a section */
private HashMap<String, Entry> entries; // key is a UTF-8 string
/** state returned by findSection */
static class Position {
int endOfFirstLine; // not including newline character
int endOfSection; // end of section, not including the blank line
// between sections
int startOfNext; // the start of the next section
}
/**
* find a section in the manifest.
*
* @param offset should point to the starting offset with in the
* raw bytes of the next section.
*
* @pos set by
*
* @return false if end of bytes has been reached, otherwise returns
* true
*/
@SuppressWarnings("fallthrough")
private boolean findSection(int offset, Position pos)
{
int i = offset, len = rawBytes.length;
int last = offset;
int next;
boolean allBlank = true;
pos.endOfFirstLine = -1;
while (i < len) {
byte b = rawBytes[i];
switch(b) {
case '\r':
if (pos.endOfFirstLine == -1)
pos.endOfFirstLine = i-1;
if ((i < len) && (rawBytes[i+1] == '\n'))
i++;
/* fall through */
case '\n':
if (pos.endOfFirstLine == -1)
pos.endOfFirstLine = i-1;
if (allBlank || (i == len-1)) {
if (i == len-1)
pos.endOfSection = i;
else
pos.endOfSection = last;
pos.startOfNext = i+1;
return true;
}
else {
// start of a new line
last = i;
allBlank = true;
}
break;
default:
allBlank = false;
break;
}
i++;
}
return false;
}
public ManifestDigester(byte[] bytes)
{
rawBytes = bytes;
entries = new HashMap<>();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Position pos = new Position();
if (!findSection(0, pos))
return; // XXX: exception?
// create an entry for main attributes
entries.put(MF_MAIN_ATTRS,
new Entry(0, pos.endOfSection + 1, pos.startOfNext, rawBytes));
int start = pos.startOfNext;
while(findSection(start, pos)) {
int len = pos.endOfFirstLine-start+1;
int sectionLen = pos.endOfSection-start+1;
int sectionLenWithBlank = pos.startOfNext-start;
if (len > 6) {
if (isNameAttr(bytes, start)) {
StringBuilder nameBuf = new StringBuilder(sectionLen);
try {
nameBuf.append(
new String(bytes, start+6, len-6, "UTF8"));
int i = start + len;
if ((i-start) < sectionLen) {
if (bytes[i] == '\r') {
i += 2;
} else {
i += 1;
}
}
while ((i-start) < sectionLen) {
if (bytes[i++] == ' ') {
// name is wrapped
int wrapStart = i;
while (((i-start) < sectionLen)
&& (bytes[i++] != '\n'));
if (bytes[i-1] != '\n')
return; // XXX: exception?
int wrapLen;
if (bytes[i-2] == '\r')
wrapLen = i-wrapStart-2;
else
wrapLen = i-wrapStart-1;
nameBuf.append(new String(bytes, wrapStart,
wrapLen, "UTF8"));
} else {
break;
}
}
entries.put(nameBuf.toString(),
new Entry(start, sectionLen, sectionLenWithBlank,
rawBytes));
} catch (java.io.UnsupportedEncodingException uee) {
throw new IllegalStateException(
"UTF8 not available on platform");
}
}
}
start = pos.startOfNext;
}
}
private boolean isNameAttr(byte[] bytes, int start)
{
return ((bytes[start] == 'N') || (bytes[start] == 'n')) &&
((bytes[start+1] == 'a') || (bytes[start+1] == 'A')) &&
((bytes[start+2] == 'm') || (bytes[start+2] == 'M')) &&
((bytes[start+3] == 'e') || (bytes[start+3] == 'E')) &&
(bytes[start+4] == ':') &&
(bytes[start+5] == ' ');
}
public static class Entry {
int offset;
int length;
int lengthWithBlankLine;
byte[] rawBytes;
boolean oldStyle;
public Entry(int offset, int length,
int lengthWithBlankLine, byte[] rawBytes)
{
this.offset = offset;
this.length = length;
this.lengthWithBlankLine = lengthWithBlankLine;
this.rawBytes = rawBytes;
}
public byte[] digest(MessageDigest md)
{
md.reset();
if (oldStyle) {
doOldStyle(md,rawBytes, offset, lengthWithBlankLine);
} else {
md.update(rawBytes, offset, lengthWithBlankLine);
}
return md.digest();
}
private void doOldStyle(MessageDigest md,
byte[] bytes,
int offset,
int length)
{
// this is too gross to even document, but here goes
// the 1.1 jar verification code ignored spaces at the
// end of lines when calculating digests, so that is
// what this code does. It only gets called if we
// are parsing a 1.1 signed signature file
int i = offset;
int start = offset;
int max = offset + length;
int prev = -1;
while(i <max) {
if ((bytes[i] == '\r') && (prev == ' ')) {
md.update(bytes, start, i-start-1);
start = i;
}
prev = bytes[i];
i++;
}
md.update(bytes, start, i-start);
}
/** Netscape doesn't include the new line. Intel and JavaSoft do */
public byte[] digestWorkaround(MessageDigest md)
{
md.reset();
md.update(rawBytes, offset, length);
return md.digest();
}
}
public Entry get(String name, boolean oldStyle) {
Entry e = entries.get(name);
if (e != null)
e.oldStyle = oldStyle;
return e;
}
public byte[] manifestDigest(MessageDigest md) {
md.reset();
md.update(rawBytes, 0, rawBytes.length);
return md.digest();
}
}

View file

@ -0,0 +1,255 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.*;
import java.io.*;
import java.security.CodeSigner;
import java.util.*;
import java.util.jar.*;
import java.util.Base64;
import sun.security.jca.Providers;
/**
* This class is used to verify each entry in a jar file with its
* manifest value.
*/
public class ManifestEntryVerifier {
private static final Debug debug = Debug.getInstance("jar");
/**
* Holder class to lazily load Sun provider. NOTE: if
* Providers.getSunProvider returned a cached provider, we could avoid the
* need for caching the provider with this holder class; we should try to
* revisit this in JDK 8.
*/
private static class SunProviderHolder {
private static final Provider instance = Providers.getSunProvider();
}
/** the created digest objects */
HashMap<String, MessageDigest> createdDigests;
/** the digests in use for a given entry*/
ArrayList<MessageDigest> digests;
/** the manifest hashes for the digests in use */
ArrayList<byte[]> manifestHashes;
private String name = null;
private Manifest man;
private boolean skip = true;
private JarEntry entry;
private CodeSigner[] signers = null;
/**
* Create a new ManifestEntryVerifier object.
*/
public ManifestEntryVerifier(Manifest man)
{
createdDigests = new HashMap<>(11);
digests = new ArrayList<>();
manifestHashes = new ArrayList<>();
this.man = man;
}
/**
* Find the hashes in the
* manifest for this entry, save them, and set the MessageDigest
* objects to calculate the hashes on the fly. If name is
* null it signifies that update/verify should ignore this entry.
*/
public void setEntry(String name, JarEntry entry)
throws IOException
{
digests.clear();
manifestHashes.clear();
this.name = name;
this.entry = entry;
skip = true;
signers = null;
if (man == null || name == null) {
return;
}
/* get the headers from the manifest for this entry */
/* if there aren't any, we can't verify any digests for this entry */
skip = false;
Attributes attr = man.getAttributes(name);
if (attr == null) {
// ugh. we should be able to remove this at some point.
// there are broken jars floating around with ./name and /name
// in the manifest, and "name" in the zip/jar file.
attr = man.getAttributes("./"+name);
if (attr == null) {
attr = man.getAttributes("/"+name);
if (attr == null)
return;
}
}
for (Map.Entry<Object,Object> se : attr.entrySet()) {
String key = se.getKey().toString();
if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST")) {
// 7 is length of "-Digest"
String algorithm = key.substring(0, key.length()-7);
MessageDigest digest = createdDigests.get(algorithm);
if (digest == null) {
try {
digest = MessageDigest.getInstance
(algorithm, SunProviderHolder.instance);
createdDigests.put(algorithm, digest);
} catch (NoSuchAlgorithmException nsae) {
// ignore
}
}
if (digest != null) {
digest.reset();
digests.add(digest);
manifestHashes.add(
Base64.getMimeDecoder().decode((String)se.getValue()));
}
}
}
}
/**
* update the digests for the digests we are interested in
*/
public void update(byte buffer) {
if (skip) return;
for (int i=0; i < digests.size(); i++) {
digests.get(i).update(buffer);
}
}
/**
* update the digests for the digests we are interested in
*/
public void update(byte[] buffer, int off, int len) {
if (skip) return;
for (int i=0; i < digests.size(); i++) {
digests.get(i).update(buffer, off, len);
}
}
/**
* get the JarEntry for this object
*/
public JarEntry getEntry()
{
return entry;
}
/**
* go through all the digests, calculating the final digest
* and comparing it to the one in the manifest. If this is
* the first time we have verified this object, remove its
* code signers from sigFileSigners and place in verifiedSigners.
*
*
*/
public CodeSigner[] verify(Hashtable<String, CodeSigner[]> verifiedSigners,
Hashtable<String, CodeSigner[]> sigFileSigners)
throws JarException
{
if (skip) {
return null;
}
if (digests.isEmpty()) {
throw new SecurityException("digest missing for " + name);
}
if (signers != null)
return signers;
for (int i=0; i < digests.size(); i++) {
MessageDigest digest = digests.get(i);
byte [] manHash = manifestHashes.get(i);
byte [] theHash = digest.digest();
if (debug != null) {
debug.println("Manifest Entry: " +
name + " digest=" + digest.getAlgorithm());
debug.println(" manifest " + toHex(manHash));
debug.println(" computed " + toHex(theHash));
debug.println();
}
if (!MessageDigest.isEqual(theHash, manHash))
throw new SecurityException(digest.getAlgorithm()+
" digest error for "+name);
}
// take it out of sigFileSigners and put it in verifiedSigners...
signers = sigFileSigners.remove(name);
if (signers != null) {
verifiedSigners.put(name, signers);
}
return signers;
}
// for the toHex function
private static final char[] hexc =
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
/**
* convert a byte array to a hex string for debugging purposes
* @param data the binary data to be converted to a hex string
* @return an ASCII hex string
*/
static String toHex(byte[] data) {
StringBuilder sb = new StringBuilder(data.length*2);
for (int i=0; i<data.length; i++) {
sb.append(hexc[(data[i] >>4) & 0x0f]);
sb.append(hexc[data[i] & 0x0f]);
}
return sb.toString();
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.InvalidKeyException;
import javax.crypto.SecretKey;
/**
* Special interface for additional MessageDigestSpi method(s).
*/
public interface MessageDigestSpi2 {
/**
* Updates the digest using the specified key.
* This is used for SSL 3.0 only, we may deprecate and remove the support
* of this in the future
*
* @param key the key whose value is to be digested.
*/
void engineUpdate(SecretKey key) throws InvalidKeyException;
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.IOException;
import java.math.BigInteger;
import java.security.spec.*;
/**
* Contains Elliptic Curve parameters.
*
* @since 1.6
* @author Andreas Sterbenz
*/
public final class NamedCurve extends ECParameterSpec {
// friendly name for toString() output
private final String name;
// well known OID
private final String oid;
// encoded form (as NamedCurve identified via OID)
private final byte[] encoded;
NamedCurve(String name, String oid, EllipticCurve curve,
ECPoint g, BigInteger n, int h) {
super(curve, g, n, h);
this.name = name;
this.oid = oid;
DerOutputStream out = new DerOutputStream();
try {
out.putOID(new ObjectIdentifier(oid));
} catch (IOException e) {
throw new RuntimeException("Internal error", e);
}
encoded = out.toByteArray();
}
public String getName() {
return name;
}
public byte[] getEncoded() {
return encoded.clone();
}
public String getObjectId() {
return oid;
}
public String toString() {
return name + " (" + oid + ")";
}
}

View file

@ -0,0 +1,659 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
/**
* Represent an ISO Object Identifier.
*
* <P>Object Identifiers are arbitrary length hierarchical identifiers.
* The individual components are numbers, and they define paths from the
* root of an ISO-managed identifier space. You will sometimes see a
* string name used instead of (or in addition to) the numerical id.
* These are synonyms for the numerical IDs, but are not widely used
* since most sites do not know all the requisite strings, while all
* sites can parse the numeric forms.
*
* <P>So for example, JavaSoft has the sole authority to assign the
* meaning to identifiers below the 1.3.6.1.4.1.42.2.17 node in the
* hierarchy, and other organizations can easily acquire the ability
* to assign such unique identifiers.
*
* @author David Brownell
* @author Amit Kapoor
* @author Hemma Prafullchandra
*/
public final
class ObjectIdentifier implements Serializable
{
/**
* We use the DER value (no tag, no length) as the internal format
* @serial
*/
private byte[] encoding = null;
private transient volatile String stringForm;
/*
* IMPORTANT NOTES FOR CODE CHANGES (bug 4811968) IN JDK 1.7.0
* ===========================================================
*
* (Almost) serialization compatibility with old versions:
*
* serialVersionUID is unchanged. Old field "component" is changed to
* type Object so that "poison" (unknown object type for old versions)
* can be put inside if there are huge components that cannot be saved
* as integers.
*
* New version use the new filed "encoding" only.
*
* Below are all 4 cases in a serialization/deserialization process:
*
* 1. old -> old: Not covered here
* 2. old -> new: There's no "encoding" field, new readObject() reads
* "components" and "componentLen" instead and inits correctly.
* 3. new -> new: "encoding" field exists, new readObject() uses it
* (ignoring the other 2 fields) and inits correctly.
* 4. new -> old: old readObject() only recognizes "components" and
* "componentLen" fields. If no huge components are involved, they
* are serialized as legal values and old object can init correctly.
* Otherwise, old object cannot recognize the form (component not int[])
* and throw a ClassNotFoundException at deserialization time.
*
* Therfore, for the first 3 cases, exact compatibility is preserved. In
* the 4th case, non-huge OID is still supportable in old versions, while
* huge OID is not.
*/
private static final long serialVersionUID = 8697030238860181294L;
/**
* Changed to Object
* @serial
*/
private Object components = null; // path from root
/**
* @serial
*/
private int componentLen = -1; // how much is used.
// Is the components field calculated?
private transient boolean componentsCalculated = false;
private void readObject(ObjectInputStream is)
throws IOException, ClassNotFoundException {
is.defaultReadObject();
if (encoding == null) { // from an old version
init((int[])components, componentLen);
}
}
private void writeObject(ObjectOutputStream os)
throws IOException {
if (!componentsCalculated) {
int[] comps = toIntArray();
if (comps != null) { // every one understands this
components = comps;
componentLen = comps.length;
} else {
components = HugeOidNotSupportedByOldJDK.theOne;
}
componentsCalculated = true;
}
os.defaultWriteObject();
}
static class HugeOidNotSupportedByOldJDK implements Serializable {
private static final long serialVersionUID = 1L;
static HugeOidNotSupportedByOldJDK theOne = new HugeOidNotSupportedByOldJDK();
}
/**
* Constructs, from a string. This string should be of the form 1.23.56.
* Validity check included.
*/
public ObjectIdentifier (String oid) throws IOException
{
int ch = '.';
int start = 0;
int end = 0;
int pos = 0;
byte[] tmp = new byte[oid.length()];
int first = 0, second;
int count = 0;
try {
String comp = null;
do {
int length = 0; // length of one section
end = oid.indexOf(ch,start);
if (end == -1) {
comp = oid.substring(start);
length = oid.length() - start;
} else {
comp = oid.substring(start,end);
length = end - start;
}
if (length > 9) {
BigInteger bignum = new BigInteger(comp);
if (count == 0) {
checkFirstComponent(bignum);
first = bignum.intValue();
} else {
if (count == 1) {
checkSecondComponent(first, bignum);
bignum = bignum.add(BigInteger.valueOf(40*first));
} else {
checkOtherComponent(count, bignum);
}
pos += pack7Oid(bignum, tmp, pos);
}
} else {
int num = Integer.parseInt(comp);
if (count == 0) {
checkFirstComponent(num);
first = num;
} else {
if (count == 1) {
checkSecondComponent(first, num);
num += 40 * first;
} else {
checkOtherComponent(count, num);
}
pos += pack7Oid(num, tmp, pos);
}
}
start = end + 1;
count++;
} while (end != -1);
checkCount(count);
encoding = new byte[pos];
System.arraycopy(tmp, 0, encoding, 0, pos);
this.stringForm = oid;
} catch (IOException ioe) { // already detected by checkXXX
throw ioe;
} catch (Exception e) {
throw new IOException("ObjectIdentifier() -- Invalid format: "
+ e.toString(), e);
}
}
/**
* Constructor, from an array of integers.
* Validity check included.
*/
public ObjectIdentifier(int[] values) throws IOException
{
checkCount(values.length);
checkFirstComponent(values[0]);
checkSecondComponent(values[0], values[1]);
for (int i=2; i<values.length; i++)
checkOtherComponent(i, values[i]);
init(values, values.length);
}
/**
* Constructor, from an ASN.1 encoded input stream.
* Validity check NOT included.
* The encoding of the ID in the stream uses "DER", a BER/1 subset.
* In this case, that means a triple { typeId, length, data }.
*
* <P><STRONG>NOTE:</STRONG> When an exception is thrown, the
* input stream has not been returned to its "initial" state.
*
* @param in DER-encoded data holding an object ID
* @exception IOException indicates a decoding error
*/
public ObjectIdentifier (DerInputStream in) throws IOException
{
byte type_id;
int bufferEnd;
/*
* Object IDs are a "universal" type, and their tag needs only
* one byte of encoding. Verify that the tag of this datum
* is that of an object ID.
*
* Then get and check the length of the ID's encoding. We set
* up so that we can use in.available() to check for the end of
* this value in the data stream.
*/
type_id = (byte) in.getByte ();
if (type_id != DerValue.tag_ObjectId)
throw new IOException (
"ObjectIdentifier() -- data isn't an object ID"
+ " (tag = " + type_id + ")"
);
int len = in.getDefiniteLength();
if (len > in.available()) {
throw new IOException("ObjectIdentifier() -- length exceeds" +
"data available. Length: " + len + ", Available: " +
in.available());
}
encoding = new byte[len];
in.getBytes(encoding);
check(encoding);
}
/*
* Constructor, from the rest of a DER input buffer;
* the tag and length have been removed/verified
* Validity check NOT included.
*/
ObjectIdentifier (DerInputBuffer buf) throws IOException
{
DerInputStream in = new DerInputStream(buf);
encoding = new byte[in.available()];
in.getBytes(encoding);
check(encoding);
}
private void init(int[] components, int length) {
int pos = 0;
byte[] tmp = new byte[length*5+1]; // +1 for empty input
if (components[1] < Integer.MAX_VALUE - components[0]*40)
pos += pack7Oid(components[0]*40+components[1], tmp, pos);
else {
BigInteger big = BigInteger.valueOf(components[1]);
big = big.add(BigInteger.valueOf(components[0]*40));
pos += pack7Oid(big, tmp, pos);
}
for (int i=2; i<length; i++) {
pos += pack7Oid(components[i], tmp, pos);
}
encoding = new byte[pos];
System.arraycopy(tmp, 0, encoding, 0, pos);
}
/**
* This method is kept for compatibility reasons. The new implementation
* does the check and conversion. All around the JDK, the method is called
* in static blocks to initialize pre-defined ObjectIdentifieies. No
* obvious performance hurt will be made after this change.
*
* Old doc: Create a new ObjectIdentifier for internal use. The values are
* neither checked nor cloned.
*/
public static ObjectIdentifier newInternal(int[] values) {
try {
return new ObjectIdentifier(values);
} catch (IOException ex) {
throw new RuntimeException(ex);
// Should not happen, internal calls always uses legal values.
}
}
/*
* n.b. the only public interface is DerOutputStream.putOID()
*/
void encode (DerOutputStream out) throws IOException
{
out.write (DerValue.tag_ObjectId, encoding);
}
/**
* Compares this identifier with another, for equality.
*
* @return true iff the names are identical.
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ObjectIdentifier == false) {
return false;
}
ObjectIdentifier other = (ObjectIdentifier)obj;
return Arrays.equals(encoding, other.encoding);
}
@Override
public int hashCode() {
return Arrays.hashCode(encoding);
}
/**
* Private helper method for serialization. To be compatible with old
* versions of JDK.
* @return components in an int array, if all the components are less than
* Integer.MAX_VALUE. Otherwise, null.
*/
private int[] toIntArray() {
int length = encoding.length;
int[] result = new int[20];
int which = 0;
int fromPos = 0;
for (int i = 0; i < length; i++) {
if ((encoding[i] & 0x80) == 0) {
// one section [fromPos..i]
if (i - fromPos + 1 > 4) {
BigInteger big = new BigInteger(pack(encoding, fromPos, i-fromPos+1, 7, 8));
if (fromPos == 0) {
result[which++] = 2;
BigInteger second = big.subtract(BigInteger.valueOf(80));
if (second.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 1) {
return null;
} else {
result[which++] = second.intValue();
}
} else {
if (big.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 1) {
return null;
} else {
result[which++] = big.intValue();
}
}
} else {
int retval = 0;
for (int j = fromPos; j <= i; j++) {
retval <<= 7;
byte tmp = encoding[j];
retval |= (tmp & 0x07f);
}
if (fromPos == 0) {
if (retval < 80) {
result[which++] = retval / 40;
result[which++] = retval % 40;
} else {
result[which++] = 2;
result[which++] = retval - 80;
}
} else {
result[which++] = retval;
}
}
fromPos = i+1;
}
if (which >= result.length) {
result = Arrays.copyOf(result, which + 10);
}
}
return Arrays.copyOf(result, which);
}
/**
* Returns a string form of the object ID. The format is the
* conventional "dot" notation for such IDs, without any
* user-friendly descriptive strings, since those strings
* will not be understood everywhere.
*/
@Override
public String toString() {
String s = stringForm;
if (s == null) {
int length = encoding.length;
StringBuilder sb = new StringBuilder(length * 4);
int fromPos = 0;
for (int i = 0; i < length; i++) {
if ((encoding[i] & 0x80) == 0) {
// one section [fromPos..i]
if (fromPos != 0) { // not the first segment
sb.append('.');
}
if (i - fromPos + 1 > 4) { // maybe big integer
BigInteger big = new BigInteger(pack(encoding, fromPos, i-fromPos+1, 7, 8));
if (fromPos == 0) {
// first section encoded with more than 4 bytes,
// must be 2.something
sb.append("2.");
sb.append(big.subtract(BigInteger.valueOf(80)));
} else {
sb.append(big);
}
} else { // small integer
int retval = 0;
for (int j = fromPos; j <= i; j++) {
retval <<= 7;
byte tmp = encoding[j];
retval |= (tmp & 0x07f);
}
if (fromPos == 0) {
if (retval < 80) {
sb.append(retval/40);
sb.append('.');
sb.append(retval%40);
} else {
sb.append("2.");
sb.append(retval - 80);
}
} else {
sb.append(retval);
}
}
fromPos = i+1;
}
}
s = sb.toString();
stringForm = s;
}
return s;
}
/**
* Repack all bits from input to output. On the both sides, only a portion
* (from the least significant bit) of the 8 bits in a byte is used. This
* number is defined as the number of useful bits (NUB) for the array. All the
* used bits from the input byte array and repacked into the output in the
* exactly same order. The output bits are aligned so that the final bit of
* the input (the least significant bit in the last byte), when repacked as
* the final bit of the output, is still at the least significant position.
* Zeroes will be padded on the left side of the first output byte if
* necessary. All unused bits in the output are also zeroed.
*
* For example: if the input is 01001100 with NUB 8, the output which
* has a NUB 6 will look like:
* 00000001 00001100
* The first 2 bits of the output bytes are unused bits. The other bits
* turn out to be 000001 001100. While the 8 bits on the right are from
* the input, the left 4 zeroes are padded to fill the 6 bits space.
*
* @param in the input byte array
* @param ioffset start point inside <code>in</code>
* @param ilength number of bytes to repack
* @param iw NUB for input
* @param ow NUB for output
* @return the repacked bytes
*/
private static byte[] pack(byte[] in, int ioffset, int ilength, int iw, int ow) {
assert (iw > 0 && iw <= 8): "input NUB must be between 1 and 8";
assert (ow > 0 && ow <= 8): "output NUB must be between 1 and 8";
if (iw == ow) {
return in.clone();
}
int bits = ilength * iw; // number of all used bits
byte[] out = new byte[(bits+ow-1)/ow];
// starting from the 0th bit in the input
int ipos = 0;
// the number of padding 0's needed in the output, skip them
int opos = (bits+ow-1)/ow*ow-bits;
while(ipos < bits) {
int count = iw - ipos%iw; // unpacked bits in current input byte
if (count > ow - opos%ow) { // free space available in output byte
count = ow - opos%ow; // choose the smaller number
}
// and move them!
out[opos/ow] |= // paste!
(((in[ioffset+ipos/iw]+256) // locate the byte (+256 so that it's never negative)
>> (iw-ipos%iw-count)) // move to the end of a byte
& ((1 << (count))-1)) // zero out all other bits
<< (ow-opos%ow-count); // move to the output position
ipos += count; // advance
opos += count; // advance
}
return out;
}
/**
* Repack from NUB 8 to a NUB 7 OID sub-identifier, remove all
* unnecessary 0 headings, set the first bit of all non-tail
* output bytes to 1 (as ITU-T Rec. X.690 8.19.2 says), and
* paste it into an existing byte array.
* @param out the existing array to be pasted into
* @param ooffset the starting position to paste
* @return the number of bytes pasted
*/
private static int pack7Oid(byte[] in, int ioffset, int ilength, byte[] out, int ooffset) {
byte[] pack = pack(in, ioffset, ilength, 8, 7);
int firstNonZero = pack.length-1; // paste at least one byte
for (int i=pack.length-2; i>=0; i--) {
if (pack[i] != 0) {
firstNonZero = i;
}
pack[i] |= 0x80;
}
System.arraycopy(pack, firstNonZero, out, ooffset, pack.length-firstNonZero);
return pack.length-firstNonZero;
}
/**
* Repack from NUB 7 to NUB 8, remove all unnecessary 0
* headings, and paste it into an existing byte array.
* @param out the existing array to be pasted into
* @param ooffset the starting position to paste
* @return the number of bytes pasted
*/
private static int pack8(byte[] in, int ioffset, int ilength, byte[] out, int ooffset) {
byte[] pack = pack(in, ioffset, ilength, 7, 8);
int firstNonZero = pack.length-1; // paste at least one byte
for (int i=pack.length-2; i>=0; i--) {
if (pack[i] != 0) {
firstNonZero = i;
}
}
System.arraycopy(pack, firstNonZero, out, ooffset, pack.length-firstNonZero);
return pack.length-firstNonZero;
}
/**
* Pack the int into a OID sub-identifier DER encoding
*/
private static int pack7Oid(int input, byte[] out, int ooffset) {
byte[] b = new byte[4];
b[0] = (byte)(input >> 24);
b[1] = (byte)(input >> 16);
b[2] = (byte)(input >> 8);
b[3] = (byte)(input);
return pack7Oid(b, 0, 4, out, ooffset);
}
/**
* Pack the BigInteger into a OID subidentifier DER encoding
*/
private static int pack7Oid(BigInteger input, byte[] out, int ooffset) {
byte[] b = input.toByteArray();
return pack7Oid(b, 0, b.length, out, ooffset);
}
/**
* Private methods to check validity of OID. They must be --
* 1. at least 2 components
* 2. all components must be non-negative
* 3. the first must be 0, 1 or 2
* 4. if the first is 0 or 1, the second must be <40
*/
/**
* Check the DER encoding. Since DER encoding defines that the integer bits
* are unsigned, so there's no need to check the MSB.
*/
private static void check(byte[] encoding) throws IOException {
int length = encoding.length;
if (length < 1 || // too short
(encoding[length - 1] & 0x80) != 0) { // not ended
throw new IOException("ObjectIdentifier() -- " +
"Invalid DER encoding, not ended");
}
for (int i=0; i<length; i++) {
// 0x80 at the beginning of a subidentifier
if (encoding[i] == (byte)0x80 &&
(i==0 || (encoding[i-1] & 0x80) == 0)) {
throw new IOException("ObjectIdentifier() -- " +
"Invalid DER encoding, useless extra octet detected");
}
}
}
private static void checkCount(int count) throws IOException {
if (count < 2) {
throw new IOException("ObjectIdentifier() -- " +
"Must be at least two oid components ");
}
}
private static void checkFirstComponent(int first) throws IOException {
if (first < 0 || first > 2) {
throw new IOException("ObjectIdentifier() -- " +
"First oid component is invalid ");
}
}
private static void checkFirstComponent(BigInteger first) throws IOException {
if (first.signum() == -1 || first.compareTo(BigInteger.TWO) > 0) {
throw new IOException("ObjectIdentifier() -- " +
"First oid component is invalid ");
}
}
private static void checkSecondComponent(int first, int second) throws IOException {
if (second < 0 || first != 2 && second > 39) {
throw new IOException("ObjectIdentifier() -- " +
"Second oid component is invalid ");
}
}
private static void checkSecondComponent(int first, BigInteger second) throws IOException {
if (second.signum() == -1 ||
first != 2 &&
second.compareTo(BigInteger.valueOf(39)) == 1) {
throw new IOException("ObjectIdentifier() -- " +
"Second oid component is invalid ");
}
}
private static void checkOtherComponent(int i, int num) throws IOException {
if (num < 0) {
throw new IOException("ObjectIdentifier() -- " +
"oid component #" + (i+1) + " must be non-negative ");
}
}
private static void checkOtherComponent(int i, BigInteger num) throws IOException {
if (num.signum() == -1) {
throw new IOException("ObjectIdentifier() -- " +
"oid component #" + (i+1) + " must be non-negative ");
}
}
}

View file

@ -0,0 +1,161 @@
/*
* Copyright (c) 2003, 2011, 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.*;
import java.nio.*;
import java.nio.charset.*;
import java.util.Arrays;
import jdk.internal.misc.SharedSecrets;
/**
* A utility class for reading passwords
*
*/
public class Password {
/** Reads user password from given input stream. */
public static char[] readPassword(InputStream in) throws IOException {
return readPassword(in, false);
}
/** Reads user password from given input stream.
* @param isEchoOn true if the password should be echoed on the screen
*/
@SuppressWarnings("fallthrough")
public static char[] readPassword(InputStream in, boolean isEchoOn)
throws IOException {
char[] consoleEntered = null;
byte[] consoleBytes = null;
try {
// Use the new java.io.Console class
Console con = null;
if (!isEchoOn && in == System.in && ((con = System.console()) != null)) {
consoleEntered = con.readPassword();
// readPassword returns "" if you just print ENTER,
// to be compatible with old Password class, change to null
if (consoleEntered != null && consoleEntered.length == 0) {
return null;
}
consoleBytes = convertToBytes(consoleEntered);
in = new ByteArrayInputStream(consoleBytes);
}
// Rest of the lines still necessary for KeyStoreLoginModule
// and when there is no console.
char[] lineBuffer;
char[] buf;
int i;
buf = lineBuffer = new char[128];
int room = buf.length;
int offset = 0;
int c;
boolean done = false;
while (!done) {
switch (c = in.read()) {
case -1:
case '\n':
done = true;
break;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else {
done = true;
break;
}
/* fall through */
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if (offset == 0) {
return null;
}
char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');
return ret;
} finally {
if (consoleEntered != null) {
Arrays.fill(consoleEntered, ' ');
}
if (consoleBytes != null) {
Arrays.fill(consoleBytes, (byte)0);
}
}
}
/**
* Change a password read from Console.readPassword() into
* its original bytes.
*
* @param pass a char[]
* @return its byte[] format, similar to new String(pass).getBytes()
*/
private static byte[] convertToBytes(char[] pass) {
if (enc == null) {
synchronized (Password.class) {
enc = SharedSecrets.getJavaIOAccess()
.charset()
.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
}
}
byte[] ba = new byte[(int)(enc.maxBytesPerChar() * pass.length)];
ByteBuffer bb = ByteBuffer.wrap(ba);
synchronized (enc) {
enc.reset().encode(CharBuffer.wrap(pass), bb, true);
}
if (bb.position() < ba.length) {
ba[bb.position()] = '\n';
}
return ba;
}
private static volatile CharsetEncoder enc;
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2015, 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.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* The Length interface defines the length of an object
*/
public class Pem {
/**
* Decodes a PEM-encoded block.
*
* @param input the input string, according to RFC 1421, can only contain
* characters in the base-64 alphabet and whitespaces.
* @return the decoded bytes
* @throws java.io.IOException if input is invalid
*/
public static byte[] decode(String input) throws IOException {
byte[] src = input.replaceAll("\\s+", "")
.getBytes(StandardCharsets.ISO_8859_1);
try {
return Base64.getDecoder().decode(src);
} catch (IllegalArgumentException e) {
throw new IOException(e);
}
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2004, 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;
/**
* An exception that denotes that an operation is pending.
* Currently used by LoginContext.
*
*/
public class PendingException extends RuntimeException {
private static final long serialVersionUID = -5201837247928788640L;
/**
* Constructs a PendingException with no detail message. A detail
* message is a String that describes this particular exception.
*/
public PendingException() {
super();
}
/**
* Constructs a PendingException with the specified detail message.
* A detail message is a String that describes this particular
* exception.
*
* @param msg the detail message.
*/
public PendingException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2009, 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.security.Permission;
/**
* A factory object that creates Permission objects.
*/
public interface PermissionFactory<T extends Permission> {
T newPermission(String name);
}

View file

@ -0,0 +1,178 @@
/*
* Copyright (c) 2004, 2006, 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.*;
import java.net.*;
import java.security.*;
import java.util.Arrays;
import sun.net.www.ParseUtil;
/**
* A utility class for getting a KeyStore instance from policy information.
* In addition, a supporting getInputStream method.
*
*/
public class PolicyUtil {
// standard PKCS11 KeyStore type
private static final String P11KEYSTORE = "PKCS11";
// reserved word
private static final String NONE = "NONE";
/*
* Fast path reading from file urls in order to avoid calling
* FileURLConnection.connect() which can be quite slow the first time
* it is called. We really should clean up FileURLConnection so that
* this is not a problem but in the meantime this fix helps reduce
* start up time noticeably for the new launcher. -- DAC
*/
public static InputStream getInputStream(URL url) throws IOException {
if ("file".equals(url.getProtocol())) {
String path = url.getFile().replace('/', File.separatorChar);
path = ParseUtil.decode(path);
return new FileInputStream(path);
} else {
return url.openStream();
}
}
/**
* this is intended for use by policytool and the policy parser to
* instantiate a KeyStore from the information in the GUI/policy file
*/
public static KeyStore getKeyStore
(URL policyUrl, // URL of policy file
String keyStoreName, // input: keyStore URL
String keyStoreType, // input: keyStore type
String keyStoreProvider, // input: keyStore provider
String storePassURL, // input: keyStore password
Debug debug)
throws KeyStoreException, MalformedURLException, IOException,
NoSuchProviderException, NoSuchAlgorithmException,
java.security.cert.CertificateException {
if (keyStoreName == null) {
throw new IllegalArgumentException("null KeyStore name");
}
char[] keyStorePassword = null;
try {
KeyStore ks;
if (keyStoreType == null) {
keyStoreType = KeyStore.getDefaultType();
}
if (P11KEYSTORE.equalsIgnoreCase(keyStoreType) &&
!NONE.equals(keyStoreName)) {
throw new IllegalArgumentException
("Invalid value (" +
keyStoreName +
") for keystore URL. If the keystore type is \"" +
P11KEYSTORE +
"\", the keystore url must be \"" +
NONE +
"\"");
}
if (keyStoreProvider != null) {
ks = KeyStore.getInstance(keyStoreType, keyStoreProvider);
} else {
ks = KeyStore.getInstance(keyStoreType);
}
if (storePassURL != null) {
URL passURL;
try {
passURL = new URL(storePassURL);
// absolute URL
} catch (MalformedURLException e) {
// relative URL
if (policyUrl == null) {
throw e;
}
passURL = new URL(policyUrl, storePassURL);
}
if (debug != null) {
debug.println("reading password"+passURL);
}
InputStream in = null;
try {
in = passURL.openStream();
keyStorePassword = Password.readPassword(in);
} finally {
if (in != null) {
in.close();
}
}
}
if (NONE.equals(keyStoreName)) {
ks.load(null, keyStorePassword);
return ks;
} else {
/*
* location of keystore is specified as absolute URL in policy
* file, or is relative to URL of policy file
*/
URL keyStoreUrl = null;
try {
keyStoreUrl = new URL(keyStoreName);
// absolute URL
} catch (MalformedURLException e) {
// relative URL
if (policyUrl == null) {
throw e;
}
keyStoreUrl = new URL(policyUrl, keyStoreName);
}
if (debug != null) {
debug.println("reading keystore"+keyStoreUrl);
}
InputStream inStream = null;
try {
inStream =
new BufferedInputStream(getInputStream(keyStoreUrl));
ks.load(inStream, keyStorePassword);
} finally {
inStream.close();
}
return ks;
}
} finally {
if (keyStorePassword != null) {
Arrays.fill(keyStorePassword, ' ');
}
}
}
}

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 1998, 2004, 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.net.URI;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
/**
* A utility class to expand properties embedded in a string.
* Strings of the form ${some.property.name} are expanded to
* be the value of the property. Also, the special ${/} property
* is expanded to be the same as file.separator. If a property
* is not set, a GeneralSecurityException will be thrown.
*
* @author Roland Schemers
*/
public class PropertyExpander {
public static class ExpandException extends GeneralSecurityException {
private static final long serialVersionUID = -7941948581406161702L;
public ExpandException(String msg) {
super(msg);
}
}
public static String expand(String value)
throws ExpandException
{
return expand(value, false);
}
public static String expand(String value, boolean encodeURL)
throws ExpandException
{
if (value == null)
return null;
int p = value.indexOf("${", 0);
// no special characters
if (p == -1) return value;
StringBuilder sb = new StringBuilder(value.length());
int max = value.length();
int i = 0; // index of last character we copied
scanner:
while (p < max) {
if (p > i) {
// copy in anything before the special stuff
sb.append(value.substring(i, p));
i = p;
}
int pe = p+2;
// do not expand ${{ ... }}
if (pe < max && value.charAt(pe) == '{') {
pe = value.indexOf("}}", pe);
if (pe == -1 || pe+2 == max) {
// append remaining chars
sb.append(value.substring(p));
break scanner;
} else {
// append as normal text
pe++;
sb.append(value.substring(p, pe+1));
}
} else {
while ((pe < max) && (value.charAt(pe) != '}')) {
pe++;
}
if (pe == max) {
// no matching '}' found, just add in as normal text
sb.append(value.substring(p, pe));
break scanner;
}
String prop = value.substring(p+2, pe);
if (prop.equals("/")) {
sb.append(java.io.File.separatorChar);
} else {
String val = System.getProperty(prop);
if (val != null) {
if (encodeURL) {
// encode 'val' unless it's an absolute URI
// at the beginning of the string buffer
try {
if (sb.length() > 0 ||
!(new URI(val)).isAbsolute()) {
val = sun.net.www.ParseUtil.encodePath(val);
}
} catch (URISyntaxException use) {
val = sun.net.www.ParseUtil.encodePath(val);
}
}
sb.append(val);
} else {
throw new ExpandException(
"unable to expand property " +
prop);
}
}
}
i = pe+1;
p = value.indexOf("${", i);
if (p == -1) {
// no more to expand. copy in any extra
if (i < max) {
sb.append(value.substring(i, max));
}
// break out of loop
break scanner;
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.util.Optional;
/**
* A domain that is registered under a "public suffix". The public suffix is
* a top-level domain under which names can be registered. For example,
* "com" and "co.uk" are public suffixes, and "example.com" and "example.co.uk"
* are registered domains.
* <p>
* The primary purpose of this class is to determine if domains are safe to
* use in various use-cases.
*/
public interface RegisteredDomain {
public enum Type {
/**
* An ICANN registered domain.
*/
ICANN,
/**
* A private registered domain.
*/
PRIVATE
}
/**
* Returns the name of the registered domain.
*
* @return the name of the registered domain
*/
String name();
/**
* Returns the type of the registered domain.
*
* @return the type of the registered domain
*/
Type type();
/**
* Returns the public suffix of the registered domain.
*
* @return the public suffix of the registered domain
*/
String publicSuffix();
/**
* Returns an {@code Optional<RegisteredDomain>} representing the
* registered part of the specified domain.
*
* {@implNote}
* The default implementation is based on the legacy
* {@code sun.net.RegisteredDomain} class which is no longer maintained.
* It should be updated or replaced with an appropriate implementation.
*
* @param domain the domain name
* @return an {@code Optional<RegisteredDomain>}; the {@code Optional} is
* empty if the domain is unknown or not registerable
* @throws NullPointerException if domain is null
*/
public static Optional<RegisteredDomain> from(String domain) {
if (domain == null) {
throw new NullPointerException();
}
return Optional.ofNullable(sun.net.RegisteredDomain.registeredDomain(domain));
}
}

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2000, 2013, 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;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "invalid null input(s)"},
{"actions.can.only.be.read.", "actions can only be 'read'"},
{"permission.name.name.syntax.invalid.",
"permission name [{0}] syntax invalid: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Credential Class not followed by a Principal Class and Name"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Principal Class not followed by a Principal Name"},
{"Principal.Name.must.be.surrounded.by.quotes",
"Principal Name must be surrounded by quotes"},
{"Principal.Name.missing.end.quote",
"Principal Name missing end quote"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"PrivateCredentialPermission Principal Class can not be a wildcard (*) value if Principal Name is not a wildcard (*) value"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tPrincipal Class = {0}\n\tPrincipal Name = {1}"},
// javax.security.auth.x500
{"provided.null.name", "provided null name"},
{"provided.null.keyword.map", "provided null keyword map"},
{"provided.null.OID.map", "provided null OID map"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"invalid null AccessControlContext provided"},
{"invalid.null.action.provided", "invalid null action provided"},
{"invalid.null.Class.provided", "invalid null Class provided"},
{"Subject.", "Subject:\n"},
{".Principal.", "\tPrincipal: "},
{".Public.Credential.", "\tPublic Credential: "},
{".Private.Credentials.inaccessible.",
"\tPrivate Credentials inaccessible\n"},
{".Private.Credential.", "\tPrivate Credential: "},
{".Private.Credential.inaccessible.",
"\tPrivate Credential inaccessible\n"},
{"Subject.is.read.only", "Subject is read-only"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"attempting to add an object which is not an instance of java.security.Principal to a Subject's Principal Set"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"attempting to add an object which is not an instance of {0}"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Invalid null input: name"},
{"No.LoginModules.configured.for.name",
"No LoginModules configured for {0}"},
{"invalid.null.Subject.provided", "invalid null Subject provided"},
{"invalid.null.CallbackHandler.provided",
"invalid null CallbackHandler provided"},
{"null.subject.logout.called.before.login",
"null subject - logout called before login"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"unable to instantiate LoginModule, {0}, because it does not provide a no-argument constructor"},
{"unable.to.instantiate.LoginModule",
"unable to instantiate LoginModule"},
{"unable.to.instantiate.LoginModule.",
"unable to instantiate LoginModule: "},
{"unable.to.find.LoginModule.class.",
"unable to find LoginModule class: "},
{"unable.to.access.LoginModule.",
"unable to access LoginModule: "},
{"Login.Failure.all.modules.ignored",
"Login Failure: all modules ignored"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: error parsing {0}:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: error adding Permission, {0}:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: error adding Entry:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "alias name not provided ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"unable to perform substitution on alias, {0}"},
{"substitution.value.prefix.unsupported",
"substitution value, {0}, unsupported"},
{"SPACE", " "},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","type can't be null"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"keystorePasswordURL can not be specified without also specifying keystore"},
{"expected.keystore.type", "expected keystore type"},
{"expected.keystore.provider", "expected keystore provider"},
{"multiple.Codebase.expressions",
"multiple Codebase expressions"},
{"multiple.SignedBy.expressions","multiple SignedBy expressions"},
{"duplicate.keystore.domain.name","duplicate keystore domain name: {0}"},
{"duplicate.keystore.name","duplicate keystore name: {0}"},
{"SignedBy.has.empty.alias","SignedBy has empty alias"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"can not specify Principal with a wildcard class without a wildcard name"},
{"expected.codeBase.or.SignedBy.or.Principal",
"expected codeBase or SignedBy or Principal"},
{"expected.permission.entry", "expected permission entry"},
{"number.", "number "},
{"expected.expect.read.end.of.file.",
"expected [{0}], read [end of file]"},
{"expected.read.end.of.file.",
"expected [;], read [end of file]"},
{"line.number.msg", "line {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"line {0}: expected [{1}], found [{2}]"},
{"null.principalClass.or.principalName",
"null principalClass or principalName"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"PKCS11 Token [{0}] Password: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"unable to instantiate Subject-based policy"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.misc.VM;
/**
*/
public class ResourcesMgr {
// intended for java.security, javax.security and sun.security resources
private final static Map<String, ResourceBundle> bundles = new ConcurrentHashMap<>();
public static String getString(String s) {
return getBundle("sun.security.util.Resources").getString(s);
}
public static String getAuthResourceString(String s) {
return getBundle("sun.security.util.AuthResources").getString(s);
}
private static ResourceBundle getBundle(String bundleName) {
if (!VM.isBooted()) {
// don't expect this be called before the system is fully initialized.
// This triggers loading of any resource bundle that should be
// be done during initialization of system class loader.
throw new InternalError("Expected to use ResourceBundle only after booted");
}
return bundles.computeIfAbsent(bundleName, ResourceBundle::getBundle);
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_de extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "Ung\u00FCltige Nulleingabe(n)"},
{"actions.can.only.be.read.", "Aktionen k\u00F6nnen nur \"lesen\" sein"},
{"permission.name.name.syntax.invalid.",
"Syntax f\u00FCr Berechtigungsnamen [{0}] ung\u00FCltig: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Nach Zugangsdatenklasse folgt keine Principal-Klasse und kein Name"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Nach Principal-Klasse folgt kein Principal-Name"},
{"Principal.Name.must.be.surrounded.by.quotes",
"Principal-Name muss in Anf\u00FChrungszeichen stehen"},
{"Principal.Name.missing.end.quote",
"Abschlie\u00DFendes Anf\u00FChrungszeichen f\u00FCr Principal-Name fehlt"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"Principal-Klasse PrivateCredentialPermission kann kein Platzhalterwert (*) sein, wenn der Principal-Name kein Platzhalterwert (*) ist"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tPrincipal-Klasse = {0}\n\tPrincipal-Name = {1}"},
// javax.security.auth.x500
{"provided.null.name", "Nullname angegeben"},
{"provided.null.keyword.map", "Null-Schl\u00FCsselwortzuordnung angegeben"},
{"provided.null.OID.map", "Null-OID-Zuordnung angegeben"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"Ung\u00FCltiger Nullwert f\u00FCr AccessControlContext angegeben"},
{"invalid.null.action.provided", "Ung\u00FCltige Nullaktion angegeben"},
{"invalid.null.Class.provided", "Ung\u00FCltige Nullklasse angegeben"},
{"Subject.", "Subjekt:\n"},
{".Principal.", "\tPrincipal: "},
{".Public.Credential.", "\t\u00D6ffentliche Zugangsdaten: "},
{".Private.Credentials.inaccessible.",
"\tKein Zugriff auf private Zugangsdaten\n"},
{".Private.Credential.", "\tPrivate Zugangsdaten: "},
{".Private.Credential.inaccessible.",
"\tKein Zugriff auf private Zugangsdaten\n"},
{"Subject.is.read.only", "Subjekt ist schreibgesch\u00FCtzt"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"Es wird versucht, ein Objekt hinzuzuf\u00FCgen, das keine Instanz von java.security.Principal f\u00FCr eine Principal-Gruppe eines Subjekts ist"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"Es wird versucht, ein Objekt hinzuzuf\u00FCgen, das keine Instanz von {0} ist"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Ung\u00FCltige Nulleingabe: Name"},
{"No.LoginModules.configured.for.name",
"F\u00FCr {0} sind keine LoginModules konfiguriert"},
{"invalid.null.Subject.provided", "Ung\u00FCltiges Nullsubjekt angegeben"},
{"invalid.null.CallbackHandler.provided",
"Ung\u00FCltiger Nullwert f\u00FCr CallbackHandler angegeben"},
{"null.subject.logout.called.before.login",
"Nullsubjekt - Abmeldung vor Anmeldung aufgerufen"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"LoginModule {0} kann nicht instanziiert werden, da es keinen argumentlosen Constructor angibt"},
{"unable.to.instantiate.LoginModule",
"LoginModule kann nicht instanziiert werden"},
{"unable.to.instantiate.LoginModule.",
"LoginModule kann nicht instanziiert werden: "},
{"unable.to.find.LoginModule.class.",
"LoginModule-Klasse kann nicht gefunden werden: "},
{"unable.to.access.LoginModule.",
"Kein Zugriff auf LoginModule m\u00F6glich: "},
{"Login.Failure.all.modules.ignored",
"Anmeldefehler: Alle Module werden ignoriert"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: Fehler beim Parsen von {0}:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: Fehler beim Hinzuf\u00FCgen von Berechtigung, {0}:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: Fehler beim Hinzuf\u00FCgen von Eintrag:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "Aliasname nicht angegeben ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"Substitution f\u00FCr Alias {0} kann nicht ausgef\u00FChrt werden"},
{"substitution.value.prefix.unsupported",
"Substitutionswert {0} nicht unterst\u00FCtzt"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","Typ kann nicht null sein"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"keystorePasswordURL kann nicht ohne Keystore angegeben werden"},
{"expected.keystore.type", "Keystore-Typ erwartet"},
{"expected.keystore.provider", "Keystore-Provider erwartet"},
{"multiple.Codebase.expressions",
"mehrere Codebase-Ausdr\u00FCcke"},
{"multiple.SignedBy.expressions","mehrere SignedBy-Ausdr\u00FCcke"},
{"duplicate.keystore.domain.name","Keystore-Domainname doppelt vorhanden: {0}"},
{"duplicate.keystore.name","Keystore-Name doppelt vorhanden: {0}"},
{"SignedBy.has.empty.alias","Leerer Alias in SignedBy"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"Principal kann nicht mit einer Platzhalterklasse ohne Platzhalternamen angegeben werden"},
{"expected.codeBase.or.SignedBy.or.Principal",
"codeBase oder SignedBy oder Principal erwartet"},
{"expected.permission.entry", "Berechtigungseintrag erwartet"},
{"number.", "Nummer "},
{"expected.expect.read.end.of.file.",
"[{0}] erwartet, [Dateiende] gelesen"},
{"expected.read.end.of.file.",
"[;] erwartet, [Dateiende] gelesen"},
{"line.number.msg", "Zeile {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"Zeile {0}: [{1}] erwartet, [{2}] gefunden"},
{"null.principalClass.or.principalName",
"principalClass oder principalName null"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"Kennwort f\u00FCr PKCS11-Token [{0}]: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"Subjektbasierte Policy kann nicht instanziiert werden"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_es extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "entradas nulas no v\u00E1lidas"},
{"actions.can.only.be.read.", "las acciones s\u00F3lo pueden 'leerse'"},
{"permission.name.name.syntax.invalid.",
"sintaxis de nombre de permiso [{0}] no v\u00E1lida: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"La clase de credencial no va seguida de una clase y nombre de principal"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"La clase de principal no va seguida de un nombre de principal"},
{"Principal.Name.must.be.surrounded.by.quotes",
"El nombre de principal debe ir entre comillas"},
{"Principal.Name.missing.end.quote",
"Faltan las comillas finales en el nombre de principal"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"La clase de principal PrivateCredentialPermission no puede ser un valor comod\u00EDn (*) si el nombre de principal no lo es tambi\u00E9n"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tClase de Principal = {0}\n\tNombre de Principal = {1}"},
// javax.security.auth.x500
{"provided.null.name", "se ha proporcionado un nombre nulo"},
{"provided.null.keyword.map", "mapa de palabras clave proporcionado nulo"},
{"provided.null.OID.map", "mapa de OID proporcionado nulo"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"se ha proporcionado un AccessControlContext nulo no v\u00E1lido"},
{"invalid.null.action.provided", "se ha proporcionado una acci\u00F3n nula no v\u00E1lida"},
{"invalid.null.Class.provided", "se ha proporcionado una clase nula no v\u00E1lida"},
{"Subject.", "Asunto:\n"},
{".Principal.", "\tPrincipal: "},
{".Public.Credential.", "\tCredencial P\u00FAblica: "},
{".Private.Credentials.inaccessible.",
"\tCredenciales Privadas Inaccesibles\n"},
{".Private.Credential.", "\tCredencial Privada: "},
{".Private.Credential.inaccessible.",
"\tCredencial Privada Inaccesible\n"},
{"Subject.is.read.only", "El asunto es de s\u00F3lo lectura"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"intentando agregar un objeto que no es una instancia de java.security.Principal al juego principal de un asunto"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"intentando agregar un objeto que no es una instancia de {0}"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Entrada nula no v\u00E1lida: nombre"},
{"No.LoginModules.configured.for.name",
"No se han configurado LoginModules para {0}"},
{"invalid.null.Subject.provided", "se ha proporcionado un asunto nulo no v\u00E1lido"},
{"invalid.null.CallbackHandler.provided",
"se ha proporcionado CallbackHandler nulo no v\u00E1lido"},
{"null.subject.logout.called.before.login",
"asunto nulo - se ha llamado al cierre de sesi\u00F3n antes del inicio de sesi\u00F3n"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"no se ha podido instanciar LoginModule, {0}, porque no incluye un constructor sin argumentos"},
{"unable.to.instantiate.LoginModule",
"no se ha podido instanciar LoginModule"},
{"unable.to.instantiate.LoginModule.",
"no se ha podido instanciar LoginModule: "},
{"unable.to.find.LoginModule.class.",
"no se ha encontrado la clase LoginModule: "},
{"unable.to.access.LoginModule.",
"no se ha podido acceder a LoginModule: "},
{"Login.Failure.all.modules.ignored",
"Fallo en inicio de sesi\u00F3n: se han ignorado todos los m\u00F3dulos"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: error de an\u00E1lisis de {0}:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: error al agregar un permiso, {0}:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: error al agregar una entrada:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "no se ha proporcionado el nombre de alias ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"no se puede realizar la sustituci\u00F3n en el alias, {0}"},
{"substitution.value.prefix.unsupported",
"valor de sustituci\u00F3n, {0}, no soportado"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","el tipo no puede ser nulo"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"keystorePasswordURL no puede especificarse sin especificar tambi\u00E9n el almac\u00E9n de claves"},
{"expected.keystore.type", "se esperaba un tipo de almac\u00E9n de claves"},
{"expected.keystore.provider", "se esperaba un proveedor de almac\u00E9n de claves"},
{"multiple.Codebase.expressions",
"expresiones m\u00FAltiples de CodeBase"},
{"multiple.SignedBy.expressions","expresiones m\u00FAltiples de SignedBy"},
{"duplicate.keystore.domain.name","nombre de dominio de almac\u00E9n de claves duplicado: {0}"},
{"duplicate.keystore.name","nombre de almac\u00E9n de claves duplicado: {0}"},
{"SignedBy.has.empty.alias","SignedBy tiene un alias vac\u00EDo"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"no se puede especificar Principal con una clase de comod\u00EDn sin un nombre de comod\u00EDn"},
{"expected.codeBase.or.SignedBy.or.Principal",
"se esperaba codeBase o SignedBy o Principal"},
{"expected.permission.entry", "se esperaba un permiso de entrada"},
{"number.", "n\u00FAmero "},
{"expected.expect.read.end.of.file.",
"se esperaba [{0}], se ha le\u00EDdo [final de archivo]"},
{"expected.read.end.of.file.",
"se esperaba [;], se ha le\u00EDdo [final de archivo]"},
{"line.number.msg", "l\u00EDnea {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"l\u00EDnea {0}: se esperaba [{1}], se ha encontrado [{2}]"},
{"null.principalClass.or.principalName",
"principalClass o principalName nulos"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"Contrase\u00F1a del Token PKCS11 [{0}]: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"no se ha podido instanciar una pol\u00EDtica basada en asunto"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_fr extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "entr\u00E9es NULL non valides"},
{"actions.can.only.be.read.", "les actions sont accessibles en lecture uniquement"},
{"permission.name.name.syntax.invalid.",
"syntaxe de nom de droit [{0}] non valide : "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Classe Credential non suivie d'une classe et d'un nom de principal"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Classe de principal non suivie d'un nom de principal"},
{"Principal.Name.must.be.surrounded.by.quotes",
"Le nom de principal doit \u00EAtre indiqu\u00E9 entre guillemets"},
{"Principal.Name.missing.end.quote",
"Guillemet fermant manquant pour le nom de principal"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"La classe de principal PrivateCredentialPermission ne peut pas \u00EAtre une valeur g\u00E9n\u00E9rique (*) si le nom de principal n'est pas une valeur g\u00E9n\u00E9rique (*)"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner :\n\tClasse de principal = {0}\n\tNom de principal = {1}"},
// javax.security.auth.x500
{"provided.null.name", "nom NULL fourni"},
{"provided.null.keyword.map", "mappage de mots-cl\u00E9s NULL fourni"},
{"provided.null.OID.map", "mappage OID NULL fourni"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"AccessControlContext NULL fourni non valide"},
{"invalid.null.action.provided", "action NULL fournie non valide"},
{"invalid.null.Class.provided", "classe NULL fournie non valide"},
{"Subject.", "Objet :\n"},
{".Principal.", "\tPrincipal : "},
{".Public.Credential.", "\tInformations d'identification publiques : "},
{".Private.Credentials.inaccessible.",
"\tInformations d'identification priv\u00E9es inaccessibles\n"},
{".Private.Credential.", "\tInformations d'identification priv\u00E9es : "},
{".Private.Credential.inaccessible.",
"\tInformations d'identification priv\u00E9es inaccessibles\n"},
{"Subject.is.read.only", "Sujet en lecture seule"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"tentative d'ajout d'un objet qui n'est pas une instance de java.security.Principal dans un ensemble de principaux du sujet"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"tentative d''ajout d''un objet qui n''est pas une instance de {0}"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag : "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Entr\u00E9e NULL non valide : nom"},
{"No.LoginModules.configured.for.name",
"Aucun LoginModule configur\u00E9 pour {0}"},
{"invalid.null.Subject.provided", "sujet NULL fourni non valide"},
{"invalid.null.CallbackHandler.provided",
"CallbackHandler NULL fourni non valide"},
{"null.subject.logout.called.before.login",
"sujet NULL - Tentative de d\u00E9connexion avant la connexion"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"impossible d''instancier LoginModule {0} car il ne fournit pas de constructeur sans argument"},
{"unable.to.instantiate.LoginModule",
"impossible d'instancier LoginModule"},
{"unable.to.instantiate.LoginModule.",
"impossible d'instancier LoginModule\u00A0: "},
{"unable.to.find.LoginModule.class.",
"classe LoginModule introuvable : "},
{"unable.to.access.LoginModule.",
"impossible d'acc\u00E9der \u00E0 LoginModule : "},
{"Login.Failure.all.modules.ignored",
"Echec de connexion : tous les modules ont \u00E9t\u00E9 ignor\u00E9s"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy : erreur d''analyse de {0} :\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy : erreur d''ajout de droit, {0} :\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy : erreur d''ajout d''entr\u00E9e :\n\t{0}"},
{"alias.name.not.provided.pe.name.", "nom d''alias non fourni ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"impossible d''effectuer une substitution pour l''alias, {0}"},
{"substitution.value.prefix.unsupported",
"valeur de substitution, {0}, non prise en charge"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","le type ne peut \u00EAtre NULL"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"Impossible de sp\u00E9cifier keystorePasswordURL sans indiquer aussi le fichier de cl\u00E9s"},
{"expected.keystore.type", "type de fichier de cl\u00E9s attendu"},
{"expected.keystore.provider", "fournisseur de fichier de cl\u00E9s attendu"},
{"multiple.Codebase.expressions",
"expressions Codebase multiples"},
{"multiple.SignedBy.expressions","expressions SignedBy multiples"},
{"duplicate.keystore.domain.name","nom de domaine de fichier de cl\u00E9s en double : {0}"},
{"duplicate.keystore.name","nom de fichier de cl\u00E9s en double : {0}"},
{"SignedBy.has.empty.alias","SignedBy poss\u00E8de un alias vide"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"impossible de sp\u00E9cifier le principal avec une classe g\u00E9n\u00E9rique sans nom g\u00E9n\u00E9rique"},
{"expected.codeBase.or.SignedBy.or.Principal",
"codeBase, SignedBy ou Principal attendu"},
{"expected.permission.entry", "entr\u00E9e de droit attendue"},
{"number.", "nombre "},
{"expected.expect.read.end.of.file.",
"attendu [{0}], lu [fin de fichier]"},
{"expected.read.end.of.file.",
"attendu [;], lu [fin de fichier]"},
{"line.number.msg", "ligne {0} : {1}"},
{"line.number.expected.expect.found.actual.",
"ligne {0} : attendu [{1}], trouv\u00E9 [{2}]"},
{"null.principalClass.or.principalName",
"principalClass ou principalName NULL"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"Mot de passe PKCS11 Token [{0}] : "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"impossible d'instancier les r\u00E8gles bas\u00E9es sur le sujet"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_it extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "input nullo/i non valido/i"},
{"actions.can.only.be.read.", "le azioni possono essere solamente 'lette'"},
{"permission.name.name.syntax.invalid.",
"sintassi [{0}] non valida per il nome autorizzazione: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"la classe di credenziali non \u00E8 seguita da un nome e una classe di principal"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"la classe di principal non \u00E8 seguita da un nome principal"},
{"Principal.Name.must.be.surrounded.by.quotes",
"il nome principal deve essere compreso tra apici"},
{"Principal.Name.missing.end.quote",
"apice di chiusura del nome principal mancante"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"la classe principal PrivateCredentialPermission non pu\u00F2 essere un valore carattere jolly (*) se il nome principal a sua volta non \u00E8 un valore carattere jolly (*)"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tclasse Principal = {0}\n\tNome Principal = {1}"},
// javax.security.auth.x500
{"provided.null.name", "il nome fornito \u00E8 nullo"},
{"provided.null.keyword.map", "specificata mappa parole chiave null"},
{"provided.null.OID.map", "specificata mappa OID null"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"fornito un valore nullo non valido per AccessControlContext"},
{"invalid.null.action.provided", "fornita un'azione nulla non valida"},
{"invalid.null.Class.provided", "fornita una classe nulla non valida"},
{"Subject.", "Oggetto:\n"},
{".Principal.", "\tPrincipal: "},
{".Public.Credential.", "\tCredenziale pubblica: "},
{".Private.Credentials.inaccessible.",
"\tImpossibile accedere alle credenziali private\n"},
{".Private.Credential.", "\tCredenziale privata: "},
{".Private.Credential.inaccessible.",
"\tImpossibile accedere alla credenziale privata\n"},
{"Subject.is.read.only", "L'oggetto \u00E8 di sola lettura"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"si \u00E8 tentato di aggiungere un oggetto che non \u00E8 un'istanza di java.security.Principal a un set principal dell'oggetto"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"si \u00E8 tentato di aggiungere un oggetto che non \u00E8 un''istanza di {0}"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Input nullo non valido: nome"},
{"No.LoginModules.configured.for.name",
"Nessun LoginModules configurato per {0}"},
{"invalid.null.Subject.provided", "fornito un valore nullo non valido per l'oggetto"},
{"invalid.null.CallbackHandler.provided",
"fornito un valore nullo non valido per CallbackHandler"},
{"null.subject.logout.called.before.login",
"oggetto nullo - il logout \u00E8 stato richiamato prima del login"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"impossibile creare un''istanza di LoginModule {0} in quanto non restituisce un argomento vuoto per il costruttore"},
{"unable.to.instantiate.LoginModule",
"impossibile creare un'istanza di LoginModule"},
{"unable.to.instantiate.LoginModule.",
"impossibile creare un'istanza di LoginModule: "},
{"unable.to.find.LoginModule.class.",
"impossibile trovare la classe LoginModule: "},
{"unable.to.access.LoginModule.",
"impossibile accedere a LoginModule "},
{"Login.Failure.all.modules.ignored",
"Errore di login: tutti i moduli sono stati ignorati"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: errore durante l''analisi di {0}:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: errore durante l''aggiunta dell''autorizzazione {0}:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: errore durante l''aggiunta della voce:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "impossibile fornire nome alias ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"impossibile eseguire una sostituzione sull''alias, {0}"},
{"substitution.value.prefix.unsupported",
"valore sostituzione, {0}, non supportato"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","il tipo non pu\u00F2 essere nullo"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"Impossibile specificare keystorePasswordURL senza specificare anche il keystore"},
{"expected.keystore.type", "tipo keystore previsto"},
{"expected.keystore.provider", "provider di keystore previsto"},
{"multiple.Codebase.expressions",
"espressioni Codebase multiple"},
{"multiple.SignedBy.expressions","espressioni SignedBy multiple"},
{"duplicate.keystore.domain.name","nome dominio keystore duplicato: {0}"},
{"duplicate.keystore.name","nome keystore duplicato: {0}"},
{"SignedBy.has.empty.alias","SignedBy presenta un alias vuoto"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"impossibile specificare un principal con una classe carattere jolly senza un nome carattere jolly"},
{"expected.codeBase.or.SignedBy.or.Principal",
"previsto codeBase o SignedBy o principal"},
{"expected.permission.entry", "prevista voce di autorizzazione"},
{"number.", "numero "},
{"expected.expect.read.end.of.file.",
"previsto [{0}], letto [end of file]"},
{"expected.read.end.of.file.",
"previsto [;], letto [end of file]"},
{"line.number.msg", "riga {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"riga {0}: previsto [{1}], trovato [{2}]"},
{"null.principalClass.or.principalName",
"principalClass o principalName nullo"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"Password per token PKCS11 [{0}]: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"impossibile creare un'istanza dei criteri basati sull'oggetto"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_ja extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "null\u306E\u5165\u529B\u306F\u7121\u52B9\u3067\u3059"},
{"actions.can.only.be.read.", "\u30A2\u30AF\u30B7\u30E7\u30F3\u306F'\u8AAD\u8FBC\u307F'\u306E\u307F\u53EF\u80FD\u3067\u3059"},
{"permission.name.name.syntax.invalid.",
"\u30A2\u30AF\u30BB\u30B9\u6A29\u540D[{0}]\u306E\u69CB\u6587\u304C\u7121\u52B9\u3067\u3059: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Credential\u30AF\u30E9\u30B9\u306E\u6B21\u306BPrincipal\u30AF\u30E9\u30B9\u304A\u3088\u3073\u540D\u524D\u304C\u3042\u308A\u307E\u305B\u3093"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Principal\u30AF\u30E9\u30B9\u306E\u6B21\u306B\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u540D\u304C\u3042\u308A\u307E\u305B\u3093"},
{"Principal.Name.must.be.surrounded.by.quotes",
"\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u540D\u306F\u5F15\u7528\u7B26\u3067\u56F2\u3080\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
{"Principal.Name.missing.end.quote",
"\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u540D\u306E\u6700\u5F8C\u306B\u5F15\u7528\u7B26\u304C\u3042\u308A\u307E\u305B\u3093"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u540D\u304C\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9(*)\u5024\u3067\u306A\u3044\u5834\u5408\u3001PrivateCredentialPermission\u306EPrincipal\u30AF\u30E9\u30B9\u3092\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9(*)\u5024\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tPrincipal\u30AF\u30E9\u30B9={0}\n\t\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u540D={1}"},
// javax.security.auth.x500
{"provided.null.name", "null\u306E\u540D\u524D\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"provided.null.keyword.map", "null\u306E\u30AD\u30FC\u30EF\u30FC\u30C9\u30FB\u30DE\u30C3\u30D7\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"provided.null.OID.map", "null\u306EOID\u30DE\u30C3\u30D7\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"\u7121\u52B9\u306Anull AccessControlContext\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"invalid.null.action.provided", "\u7121\u52B9\u306Anull\u30A2\u30AF\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"invalid.null.Class.provided", "\u7121\u52B9\u306Anull\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"Subject.", "\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8:\n"},
{".Principal.", "\t\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB: "},
{".Public.Credential.", "\t\u516C\u958B\u8CC7\u683C: "},
{".Private.Credentials.inaccessible.",
"\t\u975E\u516C\u958B\u8CC7\u683C\u306B\u306F\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093\n"},
{".Private.Credential.", "\t\u975E\u516C\u958B\u8CC7\u683C: "},
{".Private.Credential.inaccessible.",
"\t\u975E\u516C\u958B\u8CC7\u683C\u306B\u306F\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093\n"},
{"Subject.is.read.only", "\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u306F\u8AAD\u53D6\u308A\u5C02\u7528\u3067\u3059"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"java.security.Principal\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3067\u306F\u306A\u3044\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u3001\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u30FB\u30BB\u30C3\u30C8\u306B\u8FFD\u52A0\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"{0}\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3067\u306F\u306A\u3044\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u8FFD\u52A0\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "\u7121\u52B9\u306Anull\u5165\u529B: \u540D\u524D"},
{"No.LoginModules.configured.for.name",
"{0}\u7528\u306B\u69CB\u6210\u3055\u308C\u305FLoginModules\u306F\u3042\u308A\u307E\u305B\u3093"},
{"invalid.null.Subject.provided", "\u7121\u52B9\u306Anull\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"invalid.null.CallbackHandler.provided",
"\u7121\u52B9\u306Anull CallbackHandler\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F"},
{"null.subject.logout.called.before.login",
"null\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8 - \u30ED\u30B0\u30A4\u30F3\u3059\u308B\u524D\u306B\u30ED\u30B0\u30A2\u30A6\u30C8\u304C\u547C\u3073\u51FA\u3055\u308C\u307E\u3057\u305F"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"LoginModule {0}\u306F\u5F15\u6570\u3092\u53D6\u3089\u306A\u3044\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u3092\u6307\u5B9A\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u751F\u6210\u3067\u304D\u307E\u305B\u3093"},
{"unable.to.instantiate.LoginModule",
"LoginModule\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u751F\u6210\u3067\u304D\u307E\u305B\u3093"},
{"unable.to.instantiate.LoginModule.",
"LoginModule\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u751F\u6210\u3067\u304D\u307E\u305B\u3093: "},
{"unable.to.find.LoginModule.class.",
"LoginModule\u30AF\u30E9\u30B9\u3092\u691C\u51FA\u3067\u304D\u307E\u305B\u3093: "},
{"unable.to.access.LoginModule.",
"LoginModule\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093: "},
{"Login.Failure.all.modules.ignored",
"\u30ED\u30B0\u30A4\u30F3\u5931\u6557: \u3059\u3079\u3066\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306F\u7121\u8996\u3055\u308C\u307E\u3059"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: {0}\u306E\u69CB\u6587\u89E3\u6790\u30A8\u30E9\u30FC:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: \u30A2\u30AF\u30BB\u30B9\u6A29{0}\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: \u30A8\u30F3\u30C8\u30EA\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "\u5225\u540D\u306E\u6307\u5B9A\u304C\u3042\u308A\u307E\u305B\u3093({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"\u5225\u540D{0}\u306B\u5BFE\u3057\u3066\u7F6E\u63DB\u64CD\u4F5C\u304C\u3067\u304D\u307E\u305B\u3093"},
{"substitution.value.prefix.unsupported",
"\u7F6E\u63DB\u5024{0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","\u5165\u529B\u3092null\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"\u30AD\u30FC\u30B9\u30C8\u30A2\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001keystorePasswordURL\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"},
{"expected.keystore.type", "\u4E88\u60F3\u3055\u308C\u305F\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30BF\u30A4\u30D7"},
{"expected.keystore.provider", "\u4E88\u60F3\u3055\u308C\u305F\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0"},
{"multiple.Codebase.expressions",
"\u8907\u6570\u306ECodebase\u5F0F"},
{"multiple.SignedBy.expressions","\u8907\u6570\u306ESignedBy\u5F0F"},
{"duplicate.keystore.domain.name","\u91CD\u8907\u3059\u308B\u30AD\u30FC\u30B9\u30C8\u30A2\u30FB\u30C9\u30E1\u30A4\u30F3\u540D: {0}"},
{"duplicate.keystore.name","\u91CD\u8907\u3059\u308B\u30AD\u30FC\u30B9\u30C8\u30A2\u540D: {0}"},
{"SignedBy.has.empty.alias","SignedBy\u306F\u7A7A\u306E\u5225\u540D\u3092\u4FDD\u6301\u3057\u307E\u3059"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u540D\u306E\u306A\u3044\u30EF\u30A4\u30EB\u30C9\u30AB\u30FC\u30C9\u30FB\u30AF\u30E9\u30B9\u3092\u4F7F\u7528\u3057\u3066\u3001\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u3092\u6307\u5B9A\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093"},
{"expected.codeBase.or.SignedBy.or.Principal",
"\u4E88\u60F3\u3055\u308C\u305FcodeBase\u3001SignedBy\u307E\u305F\u306FPrincipal"},
{"expected.permission.entry", "\u4E88\u60F3\u3055\u308C\u305F\u30A2\u30AF\u30BB\u30B9\u6A29\u30A8\u30F3\u30C8\u30EA"},
{"number.", "\u6570 "},
{"expected.expect.read.end.of.file.",
"[{0}]\u3067\u306F\u306A\u304F[\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A]\u304C\u8AAD\u307F\u8FBC\u307E\u308C\u307E\u3057\u305F"},
{"expected.read.end.of.file.",
"[;]\u3067\u306F\u306A\u304F[\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A]\u304C\u8AAD\u307F\u8FBC\u307E\u308C\u307E\u3057\u305F"},
{"line.number.msg", "\u884C{0}: {1}"},
{"line.number.expected.expect.found.actual.",
"\u884C{0}: [{1}]\u3067\u306F\u306A\u304F[{2}]\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F"},
{"null.principalClass.or.principalName",
"null\u306EprincipalClass\u307E\u305F\u306FprincipalName"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"PKCS11\u30C8\u30FC\u30AF\u30F3[{0}]\u30D1\u30B9\u30EF\u30FC\u30C9: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u30FB\u30D9\u30FC\u30B9\u306E\u30DD\u30EA\u30B7\u30FC\u306E\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u3092\u751F\u6210\u3067\u304D\u307E\u305B\u3093"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_ko extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "\uB110 \uC785\uB825\uAC12\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4."},
{"actions.can.only.be.read.", "\uC791\uC5C5\uC740 '\uC77D\uAE30' \uC804\uC6A9\uC785\uB2C8\uB2E4."},
{"permission.name.name.syntax.invalid.",
"\uAD8C\uD55C \uC774\uB984 [{0}] \uAD6C\uBB38\uC774 \uBD80\uC801\uD569\uD568: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"\uC778\uC99D\uC11C \uD074\uB798\uC2A4 \uB2E4\uC74C\uC5D0 \uC8FC\uCCB4 \uD074\uB798\uC2A4\uC640 \uC774\uB984\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"Principal.Class.not.followed.by.a.Principal.Name",
"\uC8FC\uCCB4 \uD074\uB798\uC2A4 \uB2E4\uC74C\uC5D0 \uC8FC\uCCB4 \uC774\uB984\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"Principal.Name.must.be.surrounded.by.quotes",
"\uC8FC\uCCB4 \uC774\uB984\uC740 \uB530\uC634\uD45C\uB85C \uBB36\uC5B4\uC57C \uD569\uB2C8\uB2E4."},
{"Principal.Name.missing.end.quote",
"\uC8FC\uCCB4 \uC774\uB984\uC5D0 \uB2EB\uB294 \uB530\uC634\uD45C\uAC00 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"\uC8FC\uCCB4 \uC774\uB984\uC774 \uC640\uC77C\uB4DC \uCE74\uB4DC \uBB38\uC790(*) \uAC12\uC774 \uC544\uB2CC \uACBD\uC6B0 PrivateCredentialPermission \uC8FC\uCCB4 \uD074\uB798\uC2A4\uB294 \uC640\uC77C\uB4DC \uCE74\uB4DC \uBB38\uC790(*) \uAC12\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\t\uC8FC\uCCB4 \uD074\uB798\uC2A4 = {0}\n\t\uC8FC\uCCB4 \uC774\uB984 = {1}"},
// javax.security.auth.x500
{"provided.null.name", "\uB110 \uC774\uB984\uC744 \uC81C\uACF5\uD588\uC2B5\uB2C8\uB2E4."},
{"provided.null.keyword.map", "\uB110 \uD0A4\uC6CC\uB4DC \uB9F5\uC744 \uC81C\uACF5\uD588\uC2B5\uB2C8\uB2E4."},
{"provided.null.OID.map", "\uB110 OID \uB9F5\uC744 \uC81C\uACF5\uD588\uC2B5\uB2C8\uB2E4."},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"\uBD80\uC801\uD569\uD55C \uB110 AccessControlContext\uAC00 \uC81C\uACF5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"invalid.null.action.provided", "\uBD80\uC801\uD569\uD55C \uB110 \uC791\uC5C5\uC774 \uC81C\uACF5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"invalid.null.Class.provided", "\uBD80\uC801\uD569\uD55C \uB110 \uD074\uB798\uC2A4\uAC00 \uC81C\uACF5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"Subject.", "\uC81C\uBAA9:\n"},
{".Principal.", "\\\uC8FC\uCCB4: "},
{".Public.Credential.", "\t\uACF5\uC6A9 \uC778\uC99D\uC11C: "},
{".Private.Credentials.inaccessible.",
"\t\uC804\uC6A9 \uC778\uC99D\uC11C\uC5D0 \uC561\uC138\uC2A4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n"},
{".Private.Credential.", "\t\uC804\uC6A9 \uC778\uC99D\uC11C: "},
{".Private.Credential.inaccessible.",
"\t\uC804\uC6A9 \uC778\uC99D\uC11C\uC5D0 \uC561\uC138\uC2A4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n"},
{"Subject.is.read.only", "\uC81C\uBAA9\uC774 \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4."},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"java.security.Principal\uC758 \uC778\uC2A4\uD134\uC2A4\uAC00 \uC544\uB2CC \uAC1D\uCCB4\uB97C \uC81C\uBAA9\uC758 \uC8FC\uCCB4 \uC9D1\uD569\uC5D0 \uCD94\uAC00\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"{0}\uC758 \uC778\uC2A4\uD134\uC2A4\uAC00 \uC544\uB2CC \uAC1D\uCCB4\uB97C \uCD94\uAC00\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "\uBD80\uC801\uD569\uD55C \uB110 \uC785\uB825\uAC12: \uC774\uB984"},
{"No.LoginModules.configured.for.name",
"{0}\uC5D0 \uB300\uD574 \uAD6C\uC131\uB41C LoginModules\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"invalid.null.Subject.provided", "\uBD80\uC801\uD569\uD55C \uB110 \uC81C\uBAA9\uC774 \uC81C\uACF5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"invalid.null.CallbackHandler.provided",
"\uBD80\uC801\uD569\uD55C \uB110 CallbackHandler\uAC00 \uC81C\uACF5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"null.subject.logout.called.before.login",
"\uB110 \uC81C\uBAA9 - \uB85C\uADF8\uC778 \uC804\uC5D0 \uB85C\uADF8\uC544\uC6C3\uC774 \uD638\uCD9C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"\uC778\uC218\uAC00 \uC5C6\uB294 \uC0DD\uC131\uC790\uB97C \uC81C\uACF5\uD558\uC9C0 \uC54A\uC544 LoginModule {0}\uC744(\uB97C) \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"unable.to.instantiate.LoginModule",
"LoginModule\uC744 \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"unable.to.instantiate.LoginModule.",
"LoginModule\uC744 \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC74C: "},
{"unable.to.find.LoginModule.class.",
"LoginModule \uD074\uB798\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC74C: "},
{"unable.to.access.LoginModule.",
"LoginModule\uC5D0 \uC561\uC138\uC2A4\uD560 \uC218 \uC5C6\uC74C: "},
{"Login.Failure.all.modules.ignored",
"\uB85C\uADF8\uC778 \uC2E4\uD328: \uBAA8\uB4E0 \uBAA8\uB4C8\uC774 \uBB34\uC2DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: {0}\uC758 \uAD6C\uBB38\uC744 \uBD84\uC11D\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: {0} \uAD8C\uD55C\uC744 \uCD94\uAC00\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: \uD56D\uBAA9\uC744 \uCD94\uAC00\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "\uBCC4\uCE6D \uC774\uB984\uC774 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4({0})."},
{"unable.to.perform.substitution.on.alias.suffix",
"{0} \uBCC4\uCE6D\uC744 \uB300\uCCB4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"substitution.value.prefix.unsupported",
"\uB300\uCCB4 \uAC12 {0}\uC740(\uB294) \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","\uC720\uD615\uC740 \uB110\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"\uD0A4 \uC800\uC7A5\uC18C\uB97C \uC9C0\uC815\uD558\uC9C0 \uC54A\uACE0 keystorePasswordURL\uC744 \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"expected.keystore.type", "\uD0A4 \uC800\uC7A5\uC18C \uC720\uD615\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
{"expected.keystore.provider", "\uD0A4 \uC800\uC7A5\uC18C \uC81C\uACF5\uC790\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."},
{"multiple.Codebase.expressions",
"Codebase \uD45C\uD604\uC2DD\uC774 \uC5EC\uB7EC \uAC1C\uC785\uB2C8\uB2E4."},
{"multiple.SignedBy.expressions","SignedBy \uD45C\uD604\uC2DD\uC774 \uC5EC\uB7EC \uAC1C\uC785\uB2C8\uB2E4."},
{"duplicate.keystore.domain.name","\uC911\uBCF5\uB41C \uD0A4 \uC800\uC7A5\uC18C \uB3C4\uBA54\uC778 \uC774\uB984: {0}"},
{"duplicate.keystore.name","\uC911\uBCF5\uB41C \uD0A4 \uC800\uC7A5\uC18C \uC774\uB984: {0}"},
{"SignedBy.has.empty.alias","SignedBy\uC758 \uBCC4\uCE6D\uC774 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"\uC640\uC77C\uB4DC \uCE74\uB4DC \uBB38\uC790 \uC774\uB984 \uC5C6\uC774 \uC640\uC77C\uB4DC \uCE74\uB4DC \uBB38\uC790 \uD074\uB798\uC2A4\uB97C \uC0AC\uC6A9\uD558\uB294 \uC8FC\uCCB4\uB97C \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
{"expected.codeBase.or.SignedBy.or.Principal",
"codeBase, SignedBy \uB610\uB294 \uC8FC\uCCB4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."},
{"expected.permission.entry", "\uAD8C\uD55C \uD56D\uBAA9\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
{"number.", "\uC22B\uC790 "},
{"expected.expect.read.end.of.file.",
"[{0}]\uC774(\uAC00) \uD544\uC694\uD558\uC9C0\uB9CC [\uD30C\uC77C\uC758 \uB05D]\uAE4C\uC9C0 \uC77D\uC5C8\uC2B5\uB2C8\uB2E4."},
{"expected.read.end.of.file.",
"[;]\uC774 \uD544\uC694\uD558\uC9C0\uB9CC [\uD30C\uC77C\uC758 \uB05D]\uAE4C\uC9C0 \uC77D\uC5C8\uC2B5\uB2C8\uB2E4."},
{"line.number.msg", "{0} \uD589: {1}"},
{"line.number.expected.expect.found.actual.",
"{0} \uD589: [{1}]\uC774(\uAC00) \uD544\uC694\uD558\uC9C0\uB9CC [{2}]\uC774(\uAC00) \uBC1C\uACAC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
{"null.principalClass.or.principalName",
"principalClass \uB610\uB294 principalName\uC774 \uB110\uC785\uB2C8\uB2E4."},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"PKCS11 \uD1A0\uD070 [{0}] \uBE44\uBC00\uBC88\uD638: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"\uC81C\uBAA9 \uAE30\uBC18 \uC815\uCC45\uC744 \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_pt_BR extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "entrada(s) nula(s) inv\u00E1lida(s)"},
{"actions.can.only.be.read.", "as a\u00E7\u00F5es s\u00F3 podem ser 'lidas'"},
{"permission.name.name.syntax.invalid.",
"sintaxe inv\u00E1lida do nome da permiss\u00E3o [{0}]: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Classe da Credencial n\u00E3o seguida por um Nome e uma Classe do Principal"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Classe do Principal n\u00E3o seguida por um Nome do Principal"},
{"Principal.Name.must.be.surrounded.by.quotes",
"O Nome do Principal deve estar entre aspas"},
{"Principal.Name.missing.end.quote",
"Faltam as aspas finais no Nome do Principal"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"A Classe do Principal PrivateCredentialPermission n\u00E3o pode ser um valor curinga (*) se o Nome do Principal n\u00E3o for um valor curinga (*)"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tClasse do Principal = {0}\n\tNome do Principal = {1}"},
// javax.security.auth.x500
{"provided.null.name", "nome nulo fornecido"},
{"provided.null.keyword.map", "mapa de palavra-chave nulo fornecido"},
{"provided.null.OID.map", "mapa OID nulo fornecido"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"AccessControlContext nulo inv\u00E1lido fornecido"},
{"invalid.null.action.provided", "a\u00E7\u00E3o nula inv\u00E1lida fornecida"},
{"invalid.null.Class.provided", "Classe nula inv\u00E1lida fornecida"},
{"Subject.", "Assunto:\n"},
{".Principal.", "\tPrincipal: "},
{".Public.Credential.", "\tCredencial P\u00FAblica: "},
{".Private.Credentials.inaccessible.",
"\tCredenciais Privadas inacess\u00EDveis\n"},
{".Private.Credential.", "\tCredencial Privada: "},
{".Private.Credential.inaccessible.",
"\tCredencial Privada inacess\u00EDvel\n"},
{"Subject.is.read.only", "O Assunto \u00E9 somente para leitura"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"tentativa de adicionar um objeto que n\u00E3o \u00E9 uma inst\u00E2ncia de java.security.Principal a um conjunto de principais do Subject"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"tentativa de adicionar um objeto que n\u00E3o \u00E9 uma inst\u00E2ncia de {0}"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Entrada nula inv\u00E1lida: nome"},
{"No.LoginModules.configured.for.name",
"Nenhum LoginModule configurado para {0}"},
{"invalid.null.Subject.provided", "Subject nulo inv\u00E1lido fornecido"},
{"invalid.null.CallbackHandler.provided",
"CallbackHandler nulo inv\u00E1lido fornecido"},
{"null.subject.logout.called.before.login",
"Subject nulo - log-out chamado antes do log-in"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"n\u00E3o \u00E9 poss\u00EDvel instanciar LoginModule, {0}, porque ele n\u00E3o fornece um construtor sem argumento"},
{"unable.to.instantiate.LoginModule",
"n\u00E3o \u00E9 poss\u00EDvel instanciar LoginModule"},
{"unable.to.instantiate.LoginModule.",
"n\u00E3o \u00E9 poss\u00EDvel instanciar LoginModule: "},
{"unable.to.find.LoginModule.class.",
"n\u00E3o \u00E9 poss\u00EDvel localizar a classe LoginModule: "},
{"unable.to.access.LoginModule.",
"n\u00E3o \u00E9 poss\u00EDvel acessar LoginModule: "},
{"Login.Failure.all.modules.ignored",
"Falha de Log-in: todos os m\u00F3dulos ignorados"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: erro durante o parsing de {0}:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: erro ao adicionar a permiss\u00E3o, {0}:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: erro ao adicionar a Entrada:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "nome de alias n\u00E3o fornecido ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"n\u00E3o \u00E9 poss\u00EDvel realizar a substitui\u00E7\u00E3o no alias, {0}"},
{"substitution.value.prefix.unsupported",
"valor da substitui\u00E7\u00E3o, {0}, n\u00E3o suportado"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","o tipo n\u00E3o pode ser nulo"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"keystorePasswordURL n\u00E3o pode ser especificado sem que a \u00E1rea de armazenamento de chaves tamb\u00E9m seja especificada"},
{"expected.keystore.type", "tipo de armazenamento de chaves esperado"},
{"expected.keystore.provider", "fornecedor da \u00E1rea de armazenamento de chaves esperado"},
{"multiple.Codebase.expressions",
"v\u00E1rias express\u00F5es CodeBase"},
{"multiple.SignedBy.expressions","v\u00E1rias express\u00F5es SignedBy"},
{"duplicate.keystore.domain.name","nome do dom\u00EDnio da \u00E1rea de armazenamento de teclas duplicado: {0}"},
{"duplicate.keystore.name","nome da \u00E1rea de armazenamento de chaves duplicado: {0}"},
{"SignedBy.has.empty.alias","SignedBy tem alias vazio"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"n\u00E3o \u00E9 poss\u00EDvel especificar um principal com uma classe curinga sem um nome curinga"},
{"expected.codeBase.or.SignedBy.or.Principal",
"CodeBase ou SignedBy ou Principal esperado"},
{"expected.permission.entry", "entrada de permiss\u00E3o esperada"},
{"number.", "n\u00FAmero "},
{"expected.expect.read.end.of.file.",
"esperado [{0}], lido [fim do arquivo]"},
{"expected.read.end.of.file.",
"esperado [;], lido [fim do arquivo]"},
{"line.number.msg", "linha {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"linha {0}: esperada [{1}], encontrada [{2}]"},
{"null.principalClass.or.principalName",
"principalClass ou principalName nulo"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"Senha PKCS11 de Token [{0}]: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"n\u00E3o \u00E9 poss\u00EDvel instanciar a pol\u00EDtica com base em Subject"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_sv extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "ogiltiga null-indata"},
{"actions.can.only.be.read.", "funktioner kan endast 'l\u00E4sas'"},
{"permission.name.name.syntax.invalid.",
"syntaxen f\u00F6r beh\u00F6righetsnamnet [{0}] \u00E4r ogiltig: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Inloggningsuppgiftsklassen f\u00F6ljs inte av klass eller namn f\u00F6r identitetshavare"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Identitetshavareklassen f\u00F6ljs inte av n\u00E5got identitetshavarenamn"},
{"Principal.Name.must.be.surrounded.by.quotes",
"Identitetshavarenamnet m\u00E5ste anges inom citattecken"},
{"Principal.Name.missing.end.quote",
"Identitetshavarenamnet saknar avslutande citattecken"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"Identitetshavareklassen PrivateCredentialPermission kan inte ha n\u00E5got jokertecken (*) om inte namnet p\u00E5 identitetshavaren anges med jokertecken (*)"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tIdentitetshavareklass = {0}\n\tIdentitetshavarenamn = {1}"},
// javax.security.auth.x500
{"provided.null.name", "null-namn angavs"},
{"provided.null.keyword.map", "nullnyckelordsmappning angavs"},
{"provided.null.OID.map", "null-OID-mappning angavs"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"ogiltigt null-AccessControlContext"},
{"invalid.null.action.provided", "ogiltig null-funktion"},
{"invalid.null.Class.provided", "ogiltig null-klass"},
{"Subject.", "Subjekt:\n"},
{".Principal.", "\tIdentitetshavare: "},
{".Public.Credential.", "\tOffentlig inloggning: "},
{".Private.Credentials.inaccessible.",
"\tPrivat inloggning \u00E4r inte tillg\u00E4nglig\n"},
{".Private.Credential.", "\tPrivat inloggning: "},
{".Private.Credential.inaccessible.",
"\tPrivat inloggning \u00E4r inte tillg\u00E4nglig\n"},
{"Subject.is.read.only", "Subjektet \u00E4r skrivskyddad"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"f\u00F6rs\u00F6k att l\u00E4gga till ett objekt som inte \u00E4r en instans av java.security.Principal till ett subjekts upps\u00E4ttning av identitetshavare"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"f\u00F6rs\u00F6ker l\u00E4gga till ett objekt som inte \u00E4r en instans av {0}"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "Ogiltiga null-indata: namn"},
{"No.LoginModules.configured.for.name",
"Inga inloggningsmoduler har konfigurerats f\u00F6r {0}"},
{"invalid.null.Subject.provided", "ogiltig null-subjekt"},
{"invalid.null.CallbackHandler.provided",
"ogiltig null-CallbackHandler"},
{"null.subject.logout.called.before.login",
"null-subjekt - utloggning anropades f\u00F6re inloggning"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"kan inte instansiera LoginModule, {0}, eftersom den inte tillhandah\u00E5ller n\u00E5gon icke-argumentskonstruktor"},
{"unable.to.instantiate.LoginModule",
"kan inte instansiera LoginModule"},
{"unable.to.instantiate.LoginModule.",
"kan inte instansiera LoginModule: "},
{"unable.to.find.LoginModule.class.",
"hittar inte LoginModule-klassen: "},
{"unable.to.access.LoginModule.",
"ingen \u00E5tkomst till LoginModule: "},
{"Login.Failure.all.modules.ignored",
"Inloggningsfel: alla moduler ignoreras"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: fel vid tolkning av {0}:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: fel vid till\u00E4gg av beh\u00F6righet, {0}:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: fel vid till\u00E4gg av post:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "aliasnamn ej angivet ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"kan ej ers\u00E4tta alias, {0}"},
{"substitution.value.prefix.unsupported",
"ers\u00E4ttningsv\u00E4rde, {0}, st\u00F6ds ej"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","typen kan inte vara null"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"kan inte ange keystorePasswordURL utan att ange nyckellager"},
{"expected.keystore.type", "f\u00F6rv\u00E4ntad nyckellagertyp"},
{"expected.keystore.provider", "nyckellagerleverant\u00F6r f\u00F6rv\u00E4ntades"},
{"multiple.Codebase.expressions",
"flera CodeBase-uttryck"},
{"multiple.SignedBy.expressions","flera SignedBy-uttryck"},
{"duplicate.keystore.domain.name","dom\u00E4nnamn f\u00F6r dubbelt nyckellager: {0}"},
{"duplicate.keystore.name","namn f\u00F6r dubbelt nyckellager: {0}"},
{"SignedBy.has.empty.alias","SignedBy har ett tomt alias"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"kan inte ange identitetshavare med en jokerteckenklass utan ett jokerteckennamn"},
{"expected.codeBase.or.SignedBy.or.Principal",
"f\u00F6rv\u00E4ntad codeBase eller SignedBy eller identitetshavare"},
{"expected.permission.entry", "f\u00F6rv\u00E4ntade beh\u00F6righetspost"},
{"number.", "nummer"},
{"expected.expect.read.end.of.file.",
"f\u00F6rv\u00E4ntade [{0}], l\u00E4ste [filslut]"},
{"expected.read.end.of.file.",
"f\u00F6rv\u00E4ntade [;], l\u00E4ste [filslut]"},
{"line.number.msg", "rad {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"rad {0}: f\u00F6rv\u00E4ntade [{1}], hittade [{2}]"},
{"null.principalClass.or.principalName",
"null-principalClass eller -principalName"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"L\u00F6senord f\u00F6r PKCS11-token [{0}]: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"kan inte instansiera subjektbaserad policy"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_zh_CN extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "\u65E0\u6548\u7684\u7A7A\u8F93\u5165"},
{"actions.can.only.be.read.", "\u64CD\u4F5C\u53EA\u80FD\u4E3A '\u8BFB\u53D6'"},
{"permission.name.name.syntax.invalid.",
"\u6743\u9650\u540D\u79F0 [{0}] \u8BED\u6CD5\u65E0\u6548: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"\u8EAB\u4EFD\u8BC1\u660E\u7C7B\u540E\u9762\u672A\u8DDF\u968F\u4E3B\u7528\u6237\u7C7B\u53CA\u540D\u79F0"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"\u4E3B\u7528\u6237\u7C7B\u540E\u9762\u672A\u8DDF\u968F\u4E3B\u7528\u6237\u540D\u79F0"},
{"Principal.Name.must.be.surrounded.by.quotes",
"\u4E3B\u7528\u6237\u540D\u79F0\u5FC5\u987B\u653E\u5728\u5F15\u53F7\u5185"},
{"Principal.Name.missing.end.quote",
"\u4E3B\u7528\u6237\u540D\u79F0\u7F3A\u5C11\u53F3\u5F15\u53F7"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"\u5982\u679C\u4E3B\u7528\u6237\u540D\u79F0\u4E0D\u662F\u901A\u914D\u7B26 (*) \u503C, \u90A3\u4E48 PrivateCredentialPermission \u4E3B\u7528\u6237\u7C7B\u4E0D\u80FD\u662F\u901A\u914D\u7B26 (*) \u503C"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\t\u4E3B\u7528\u6237\u7C7B = {0}\n\t\u4E3B\u7528\u6237\u540D\u79F0 = {1}"},
// javax.security.auth.x500
{"provided.null.name", "\u63D0\u4F9B\u7684\u540D\u79F0\u4E3A\u7A7A\u503C"},
{"provided.null.keyword.map", "\u63D0\u4F9B\u7684\u5173\u952E\u5B57\u6620\u5C04\u4E3A\u7A7A\u503C"},
{"provided.null.OID.map", "\u63D0\u4F9B\u7684 OID \u6620\u5C04\u4E3A\u7A7A\u503C"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"\u63D0\u4F9B\u4E86\u65E0\u6548\u7684\u7A7A AccessControlContext"},
{"invalid.null.action.provided", "\u63D0\u4F9B\u4E86\u65E0\u6548\u7684\u7A7A\u64CD\u4F5C"},
{"invalid.null.Class.provided", "\u63D0\u4F9B\u4E86\u65E0\u6548\u7684\u7A7A\u7C7B"},
{"Subject.", "\u4E3B\u9898: \n"},
{".Principal.", "\t\u4E3B\u7528\u6237: "},
{".Public.Credential.", "\t\u516C\u5171\u8EAB\u4EFD\u8BC1\u660E: "},
{".Private.Credentials.inaccessible.",
"\t\u65E0\u6CD5\u8BBF\u95EE\u4E13\u7528\u8EAB\u4EFD\u8BC1\u660E\n"},
{".Private.Credential.", "\t\u4E13\u7528\u8EAB\u4EFD\u8BC1\u660E: "},
{".Private.Credential.inaccessible.",
"\t\u65E0\u6CD5\u8BBF\u95EE\u4E13\u7528\u8EAB\u4EFD\u8BC1\u660E\n"},
{"Subject.is.read.only", "\u4E3B\u9898\u4E3A\u53EA\u8BFB"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"\u6B63\u5728\u5C1D\u8BD5\u5C06\u4E00\u4E2A\u975E java.security.Principal \u5B9E\u4F8B\u7684\u5BF9\u8C61\u6DFB\u52A0\u5230\u4E3B\u9898\u7684\u4E3B\u7528\u6237\u96C6\u4E2D"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"\u6B63\u5728\u5C1D\u8BD5\u6DFB\u52A0\u4E00\u4E2A\u975E{0}\u5B9E\u4F8B\u7684\u5BF9\u8C61"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "\u65E0\u6548\u7A7A\u8F93\u5165: \u540D\u79F0"},
{"No.LoginModules.configured.for.name",
"\u6CA1\u6709\u4E3A{0}\u914D\u7F6E LoginModules"},
{"invalid.null.Subject.provided", "\u63D0\u4F9B\u4E86\u65E0\u6548\u7684\u7A7A\u4E3B\u9898"},
{"invalid.null.CallbackHandler.provided",
"\u63D0\u4F9B\u4E86\u65E0\u6548\u7684\u7A7A CallbackHandler"},
{"null.subject.logout.called.before.login",
"\u7A7A\u4E3B\u9898 - \u5728\u767B\u5F55\u4E4B\u524D\u8C03\u7528\u4E86\u6CE8\u9500"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"\u65E0\u6CD5\u5B9E\u4F8B\u5316 LoginModule, {0}, \u56E0\u4E3A\u5B83\u672A\u63D0\u4F9B\u4E00\u4E2A\u65E0\u53C2\u6570\u6784\u9020\u5668"},
{"unable.to.instantiate.LoginModule",
"\u65E0\u6CD5\u5B9E\u4F8B\u5316 LoginModule"},
{"unable.to.instantiate.LoginModule.",
"\u65E0\u6CD5\u5B9E\u4F8B\u5316 LoginModule: "},
{"unable.to.find.LoginModule.class.",
"\u65E0\u6CD5\u627E\u5230 LoginModule \u7C7B: "},
{"unable.to.access.LoginModule.",
"\u65E0\u6CD5\u8BBF\u95EE LoginModule: "},
{"Login.Failure.all.modules.ignored",
"\u767B\u5F55\u5931\u8D25: \u5FFD\u7565\u6240\u6709\u6A21\u5757"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: \u89E3\u6790{0}\u65F6\u51FA\u9519:\n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: \u6DFB\u52A0\u6743\u9650{0}\u65F6\u51FA\u9519:\n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: \u6DFB\u52A0\u6761\u76EE\u65F6\u51FA\u9519:\n\t{0}"},
{"alias.name.not.provided.pe.name.", "\u672A\u63D0\u4F9B\u522B\u540D ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"\u65E0\u6CD5\u5728\u522B\u540D {0} \u4E0A\u6267\u884C\u66FF\u4EE3"},
{"substitution.value.prefix.unsupported",
"\u66FF\u4EE3\u503C{0}\u4E0D\u53D7\u652F\u6301"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A\u503C"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"\u4E0D\u6307\u5B9A\u5BC6\u94A5\u5E93\u65F6\u65E0\u6CD5\u6307\u5B9A keystorePasswordURL"},
{"expected.keystore.type", "\u5E94\u4E3A\u5BC6\u94A5\u5E93\u7C7B\u578B"},
{"expected.keystore.provider", "\u5E94\u4E3A\u5BC6\u94A5\u5E93\u63D0\u4F9B\u65B9"},
{"multiple.Codebase.expressions",
"\u591A\u4E2A\u4EE3\u7801\u5E93\u8868\u8FBE\u5F0F"},
{"multiple.SignedBy.expressions","\u591A\u4E2A SignedBy \u8868\u8FBE\u5F0F"},
{"duplicate.keystore.domain.name","\u5BC6\u94A5\u5E93\u57DF\u540D\u91CD\u590D: {0}"},
{"duplicate.keystore.name","\u5BC6\u94A5\u5E93\u540D\u79F0\u91CD\u590D: {0}"},
{"SignedBy.has.empty.alias","SignedBy \u6709\u7A7A\u522B\u540D"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"\u6CA1\u6709\u901A\u914D\u7B26\u540D\u79F0, \u65E0\u6CD5\u4F7F\u7528\u901A\u914D\u7B26\u7C7B\u6307\u5B9A\u4E3B\u7528\u6237"},
{"expected.codeBase.or.SignedBy.or.Principal",
"\u5E94\u4E3A codeBase, SignedBy \u6216\u4E3B\u7528\u6237"},
{"expected.permission.entry", "\u5E94\u4E3A\u6743\u9650\u6761\u76EE"},
{"number.", "\u7F16\u53F7 "},
{"expected.expect.read.end.of.file.",
"\u5E94\u4E3A [{0}], \u8BFB\u53D6\u7684\u662F [\u6587\u4EF6\u7ED3\u5C3E]"},
{"expected.read.end.of.file.",
"\u5E94\u4E3A [;], \u8BFB\u53D6\u7684\u662F [\u6587\u4EF6\u7ED3\u5C3E]"},
{"line.number.msg", "\u5217{0}: {1}"},
{"line.number.expected.expect.found.actual.",
"\u884C\u53F7 {0}: \u5E94\u4E3A [{1}], \u627E\u5230 [{2}]"},
{"null.principalClass.or.principalName",
"principalClass \u6216 principalName \u4E3A\u7A7A\u503C"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"PKCS11 \u6807\u8BB0 [{0}] \u53E3\u4EE4: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"\u65E0\u6CD5\u5B9E\u4F8B\u5316\u57FA\u4E8E\u4E3B\u9898\u7684\u7B56\u7565"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
/**
* This class represents the <code>ResourceBundle</code>
* for javax.security.auth and sun.security.
*
*/
public class Resources_zh_TW extends java.util.ListResourceBundle {
private static final Object[][] contents = {
// javax.security.auth.PrivateCredentialPermission
{"invalid.null.input.s.", "\u7121\u6548\u7A7A\u503C\u8F38\u5165"},
{"actions.can.only.be.read.", "\u52D5\u4F5C\u53EA\u80FD\u88AB\u300C\u8B80\u53D6\u300D"},
{"permission.name.name.syntax.invalid.",
"\u6B0A\u9650\u540D\u7A31 [{0}] \u662F\u7121\u6548\u7684\u8A9E\u6CD5: "},
{"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
"Credential \u985E\u5225\u5F8C\u9762\u4E0D\u662F Principal \u985E\u5225\u53CA\u540D\u7A31"},
{"Principal.Class.not.followed.by.a.Principal.Name",
"Principal \u985E\u5225\u5F8C\u9762\u4E0D\u662F Principal \u540D\u7A31"},
{"Principal.Name.must.be.surrounded.by.quotes",
"Principal \u540D\u7A31\u5FC5\u9808\u4EE5\u5F15\u865F\u5708\u4F4F"},
{"Principal.Name.missing.end.quote",
"Principal \u540D\u7A31\u7F3A\u5C11\u4E0B\u5F15\u865F"},
{"PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value",
"\u5982\u679C Principal \u540D\u7A31\u4E0D\u662F\u4E00\u500B\u842C\u7528\u5B57\u5143 (*) \u503C\uFF0C\u90A3\u9EBC PrivateCredentialPermission Principal \u985E\u5225\u5C31\u4E0D\u80FD\u662F\u842C\u7528\u5B57\u5143 (*) \u503C"},
{"CredOwner.Principal.Class.class.Principal.Name.name",
"CredOwner:\n\tPrincipal \u985E\u5225 = {0}\n\tPrincipal \u540D\u7A31 = {1}"},
// javax.security.auth.x500
{"provided.null.name", "\u63D0\u4F9B\u7A7A\u503C\u540D\u7A31"},
{"provided.null.keyword.map", "\u63D0\u4F9B\u7A7A\u503C\u95DC\u9375\u5B57\u5C0D\u6620"},
{"provided.null.OID.map", "\u63D0\u4F9B\u7A7A\u503C OID \u5C0D\u6620"},
// javax.security.auth.Subject
{"NEWLINE", "\n"},
{"invalid.null.AccessControlContext.provided",
"\u63D0\u4F9B\u7121\u6548\u7684\u7A7A\u503C AccessControlContext"},
{"invalid.null.action.provided", "\u63D0\u4F9B\u7121\u6548\u7684\u7A7A\u503C\u52D5\u4F5C"},
{"invalid.null.Class.provided", "\u63D0\u4F9B\u7121\u6548\u7684\u7A7A\u503C\u985E\u5225"},
{"Subject.", "\u4E3B\u984C:\n"},
{".Principal.", "\tPrincipal: "},
{".Public.Credential.", "\t\u516C\u7528\u8B49\u660E\u8CC7\u6599: "},
{".Private.Credentials.inaccessible.",
"\t\u79C1\u4EBA\u8B49\u660E\u8CC7\u6599\u7121\u6CD5\u5B58\u53D6\n"},
{".Private.Credential.", "\t\u79C1\u4EBA\u8B49\u660E\u8CC7\u6599: "},
{".Private.Credential.inaccessible.",
"\t\u79C1\u4EBA\u8B49\u660E\u8CC7\u6599\u7121\u6CD5\u5B58\u53D6\n"},
{"Subject.is.read.only", "\u4E3B\u984C\u70BA\u552F\u8B80"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set",
"\u8A66\u5716\u65B0\u589E\u4E00\u500B\u975E java.security.Principal \u57F7\u884C\u8655\u7406\u7684\u7269\u4EF6\u81F3\u4E3B\u984C\u7684 Principal \u7FA4\u4E2D"},
{"attempting.to.add.an.object.which.is.not.an.instance.of.class",
"\u8A66\u5716\u65B0\u589E\u4E00\u500B\u975E {0} \u57F7\u884C\u8655\u7406\u7684\u7269\u4EF6"},
// javax.security.auth.login.AppConfigurationEntry
{"LoginModuleControlFlag.", "LoginModuleControlFlag: "},
// javax.security.auth.login.LoginContext
{"Invalid.null.input.name", "\u7121\u6548\u7A7A\u503C\u8F38\u5165: \u540D\u7A31"},
{"No.LoginModules.configured.for.name",
"\u7121\u91DD\u5C0D {0} \u8A2D\u5B9A\u7684 LoginModules"},
{"invalid.null.Subject.provided", "\u63D0\u4F9B\u7121\u6548\u7A7A\u503C\u4E3B\u984C"},
{"invalid.null.CallbackHandler.provided",
"\u63D0\u4F9B\u7121\u6548\u7A7A\u503C CallbackHandler"},
{"null.subject.logout.called.before.login",
"\u7A7A\u503C\u4E3B\u984C - \u5728\u767B\u5165\u4E4B\u524D\u5373\u547C\u53EB\u767B\u51FA"},
{"unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor",
"\u7121\u6CD5\u5275\u8A2D LoginModule\uFF0C{0}\uFF0C\u56E0\u70BA\u5B83\u4E26\u672A\u63D0\u4F9B\u975E\u5F15\u6578\u7684\u5EFA\u69CB\u5B50"},
{"unable.to.instantiate.LoginModule",
"\u7121\u6CD5\u5EFA\u7ACB LoginModule"},
{"unable.to.instantiate.LoginModule.",
"\u7121\u6CD5\u5EFA\u7ACB LoginModule: "},
{"unable.to.find.LoginModule.class.",
"\u627E\u4E0D\u5230 LoginModule \u985E\u5225: "},
{"unable.to.access.LoginModule.",
"\u7121\u6CD5\u5B58\u53D6 LoginModule: "},
{"Login.Failure.all.modules.ignored",
"\u767B\u5165\u5931\u6557: \u5FFD\u7565\u6240\u6709\u6A21\u7D44"},
// sun.security.provider.PolicyFile
{"java.security.policy.error.parsing.policy.message",
"java.security.policy: \u5256\u6790\u932F\u8AA4 {0}: \n\t{1}"},
{"java.security.policy.error.adding.Permission.perm.message",
"java.security.policy: \u65B0\u589E\u6B0A\u9650\u932F\u8AA4 {0}: \n\t{1}"},
{"java.security.policy.error.adding.Entry.message",
"java.security.policy: \u65B0\u589E\u9805\u76EE\u932F\u8AA4: \n\t{0}"},
{"alias.name.not.provided.pe.name.", "\u672A\u63D0\u4F9B\u5225\u540D\u540D\u7A31 ({0})"},
{"unable.to.perform.substitution.on.alias.suffix",
"\u7121\u6CD5\u5C0D\u5225\u540D\u57F7\u884C\u66FF\u63DB\uFF0C{0}"},
{"substitution.value.prefix.unsupported",
"\u4E0D\u652F\u63F4\u7684\u66FF\u63DB\u503C\uFF0C{0}"},
{"LPARAM", "("},
{"RPARAM", ")"},
{"type.can.t.be.null","\u8F38\u5165\u4E0D\u80FD\u70BA\u7A7A\u503C"},
// sun.security.provider.PolicyParser
{"keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore",
"\u6307\u5B9A keystorePasswordURL \u9700\u8981\u540C\u6642\u6307\u5B9A\u91D1\u9470\u5132\u5B58\u5EAB"},
{"expected.keystore.type", "\u9810\u671F\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u985E\u578B"},
{"expected.keystore.provider", "\u9810\u671F\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u63D0\u4F9B\u8005"},
{"multiple.Codebase.expressions",
"\u591A\u91CD Codebase \u8868\u793A\u5F0F"},
{"multiple.SignedBy.expressions","\u591A\u91CD SignedBy \u8868\u793A\u5F0F"},
{"duplicate.keystore.domain.name","\u91CD\u8907\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u7DB2\u57DF\u540D\u7A31: {0}"},
{"duplicate.keystore.name","\u91CD\u8907\u7684\u91D1\u9470\u5132\u5B58\u5EAB\u540D\u7A31: {0}"},
{"SignedBy.has.empty.alias","SignedBy \u6709\u7A7A\u5225\u540D"},
{"can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name",
"\u6C92\u6709\u842C\u7528\u5B57\u5143\u540D\u7A31\uFF0C\u7121\u6CD5\u6307\u5B9A\u542B\u6709\u842C\u7528\u5B57\u5143\u985E\u5225\u7684 Principal"},
{"expected.codeBase.or.SignedBy.or.Principal",
"\u9810\u671F\u7684 codeBase \u6216 SignedBy \u6216 Principal"},
{"expected.permission.entry", "\u9810\u671F\u7684\u6B0A\u9650\u9805\u76EE"},
{"number.", "\u865F\u78BC "},
{"expected.expect.read.end.of.file.",
"\u9810\u671F\u7684 [{0}], \u8B80\u53D6 [end of file]"},
{"expected.read.end.of.file.",
"\u9810\u671F\u7684 [;], \u8B80\u53D6 [end of file]"},
{"line.number.msg", "\u884C {0}: {1}"},
{"line.number.expected.expect.found.actual.",
"\u884C {0}: \u9810\u671F\u7684 [{1}]\uFF0C\u767C\u73FE [{2}]"},
{"null.principalClass.or.principalName",
"\u7A7A\u503C principalClass \u6216 principalName"},
// sun.security.pkcs11.SunPKCS11
{"PKCS11.Token.providerName.Password.",
"PKCS11 \u8A18\u865F [{0}] \u5BC6\u78BC: "},
/* --- DEPRECATED --- */
// javax.security.auth.Policy
{"unable.to.instantiate.Subject.based.policy",
"\u7121\u6CD5\u5EFA\u7ACB\u4E3B\u984C\u5F0F\u7684\u539F\u5247"}
};
/**
* Returns the contents of this <code>ResourceBundle</code>.
*
* @return the contents of this <code>ResourceBundle</code>.
*/
@Override
public Object[][] getContents() {
return contents;
}
}

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.net.SocketPermission;
import java.net.NetPermission;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Permission;
import java.security.BasicPermission;
import java.security.SecurityPermission;
import java.security.AllPermission;
import sun.security.action.GetPropertyAction;
/**
* Permission constants and string constants used to create permissions
* used throughout the JDK.
*/
public final class SecurityConstants {
// Cannot create one of these
private SecurityConstants () {
}
// Commonly used string constants for permission actions used by
// SecurityManager. Declare here for shortcut when checking permissions
// in FilePermission, SocketPermission, and PropertyPermission.
public static final String FILE_DELETE_ACTION = "delete";
public static final String FILE_EXECUTE_ACTION = "execute";
public static final String FILE_READ_ACTION = "read";
public static final String FILE_WRITE_ACTION = "write";
public static final String FILE_READLINK_ACTION = "readlink";
public static final String SOCKET_RESOLVE_ACTION = "resolve";
public static final String SOCKET_CONNECT_ACTION = "connect";
public static final String SOCKET_LISTEN_ACTION = "listen";
public static final String SOCKET_ACCEPT_ACTION = "accept";
public static final String SOCKET_CONNECT_ACCEPT_ACTION = "connect,accept";
public static final String PROPERTY_RW_ACTION = "read,write";
public static final String PROPERTY_READ_ACTION = "read";
public static final String PROPERTY_WRITE_ACTION = "write";
// Permission constants used in the various checkPermission() calls in JDK.
// java.lang.Class, java.lang.SecurityManager, java.lang.System,
// java.net.URLConnection, java.security.AllPermission, java.security.Policy,
// sun.security.provider.PolicyFile
public static final AllPermission ALL_PERMISSION = new AllPermission();
// java.net.URL
public static final NetPermission SPECIFY_HANDLER_PERMISSION =
new NetPermission("specifyStreamHandler");
// java.net.ProxySelector
public static final NetPermission SET_PROXYSELECTOR_PERMISSION =
new NetPermission("setProxySelector");
// java.net.ProxySelector
public static final NetPermission GET_PROXYSELECTOR_PERMISSION =
new NetPermission("getProxySelector");
// java.net.CookieHandler
public static final NetPermission SET_COOKIEHANDLER_PERMISSION =
new NetPermission("setCookieHandler");
// java.net.CookieHandler
public static final NetPermission GET_COOKIEHANDLER_PERMISSION =
new NetPermission("getCookieHandler");
// java.net.ResponseCache
public static final NetPermission SET_RESPONSECACHE_PERMISSION =
new NetPermission("setResponseCache");
// java.net.ResponseCache
public static final NetPermission GET_RESPONSECACHE_PERMISSION =
new NetPermission("getResponseCache");
// java.lang.SecurityManager, sun.applet.AppletPanel
public static final RuntimePermission CREATE_CLASSLOADER_PERMISSION =
new RuntimePermission("createClassLoader");
// java.lang.SecurityManager
public static final RuntimePermission CHECK_MEMBER_ACCESS_PERMISSION =
new RuntimePermission("accessDeclaredMembers");
// java.lang.SecurityManager, sun.applet.AppletSecurity
public static final RuntimePermission MODIFY_THREAD_PERMISSION =
new RuntimePermission("modifyThread");
// java.lang.SecurityManager, sun.applet.AppletSecurity
public static final RuntimePermission MODIFY_THREADGROUP_PERMISSION =
new RuntimePermission("modifyThreadGroup");
// java.lang.Class
public static final RuntimePermission GET_PD_PERMISSION =
new RuntimePermission("getProtectionDomain");
// java.lang.Class, java.lang.ClassLoader, java.lang.Thread
public static final RuntimePermission GET_CLASSLOADER_PERMISSION =
new RuntimePermission("getClassLoader");
// java.lang.Thread
public static final RuntimePermission STOP_THREAD_PERMISSION =
new RuntimePermission("stopThread");
// java.lang.Thread
public static final RuntimePermission GET_STACK_TRACE_PERMISSION =
new RuntimePermission("getStackTrace");
// java.security.AccessControlContext
public static final SecurityPermission CREATE_ACC_PERMISSION =
new SecurityPermission("createAccessControlContext");
// java.security.AccessControlContext
public static final SecurityPermission GET_COMBINER_PERMISSION =
new SecurityPermission("getDomainCombiner");
// java.security.Policy, java.security.ProtectionDomain
public static final SecurityPermission GET_POLICY_PERMISSION =
new SecurityPermission ("getPolicy");
// java.lang.SecurityManager
public static final SocketPermission LOCAL_LISTEN_PERMISSION =
new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION);
public static final String PROVIDER_VER =
GetPropertyAction.privilegedGetProperty("java.specification.version");
}

View file

@ -0,0 +1,855 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.CodeSigner;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.Timestamp;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarException;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import sun.security.jca.Providers;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.SignerInfo;
public class SignatureFileVerifier {
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
/**
* Holder class to delay initialization of DisabledAlgorithmConstraints
* until needed.
*/
private static class ConfigurationHolder {
static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
}
private ArrayList<CodeSigner[]> signerCache;
private static final String ATTR_DIGEST =
("-DIGEST-" + ManifestDigester.MF_MAIN_ATTRS).toUpperCase
(Locale.ENGLISH);
/** the PKCS7 block for this .DSA/.RSA/.EC file */
private PKCS7 block;
/** the raw bytes of the .SF file */
private byte[] sfBytes;
/** the name of the signature block file, uppercased and without
* the extension (.DSA/.RSA/.EC)
*/
private String name;
/** the ManifestDigester */
private ManifestDigester md;
/** cache of created MessageDigest objects */
private HashMap<String, MessageDigest> createdDigests;
/* workaround for parsing Netscape jars */
private boolean workaround = false;
/* for generating certpath objects */
private CertificateFactory certificateFactory = null;
/** Algorithms that have been checked if they are weak. */
private Map<String, Boolean> permittedAlgs= new HashMap<>();
/** TSA timestamp of signed jar. The newest timestamp is used. If there
* was no TSA timestamp used when signed, current time is used ("null").
*/
private Timestamp timestamp = null;
/**
* Create the named SignatureFileVerifier.
*
* @param name the name of the signature block file (.DSA/.RSA/.EC)
*
* @param rawBytes the raw bytes of the signature block file
*/
public SignatureFileVerifier(ArrayList<CodeSigner[]> signerCache,
ManifestDigester md,
String name,
byte[] rawBytes)
throws IOException, CertificateException
{
// new PKCS7() calls CertificateFactory.getInstance()
// need to use local providers here, see Providers class
Object obj = null;
try {
obj = Providers.startJarVerification();
block = new PKCS7(rawBytes);
sfBytes = block.getContentInfo().getData();
certificateFactory = CertificateFactory.getInstance("X509");
} finally {
Providers.stopJarVerification(obj);
}
this.name = name.substring(0, name.lastIndexOf('.'))
.toUpperCase(Locale.ENGLISH);
this.md = md;
this.signerCache = signerCache;
}
/**
* returns true if we need the .SF file
*/
public boolean needSignatureFileBytes()
{
return sfBytes == null;
}
/**
* returns true if we need this .SF file.
*
* @param name the name of the .SF file without the extension
*
*/
public boolean needSignatureFile(String name)
{
return this.name.equalsIgnoreCase(name);
}
/**
* used to set the raw bytes of the .SF file when it
* is external to the signature block file.
*/
public void setSignatureFile(byte[] sfBytes)
{
this.sfBytes = sfBytes;
}
/**
* Utility method used by JarVerifier and JarSigner
* to determine the signature file names and PKCS7 block
* files names that are supported
*
* @param s file name
* @return true if the input file name is a supported
* Signature File or PKCS7 block file name
*/
public static boolean isBlockOrSF(String s) {
// we currently only support DSA and RSA PKCS7 blocks
return s.endsWith(".SF")
|| s.endsWith(".DSA")
|| s.endsWith(".RSA")
|| s.endsWith(".EC");
}
/**
* Yet another utility method used by JarVerifier and JarSigner
* to determine what files are signature related, which includes
* the MANIFEST, SF files, known signature block files, and other
* unknown signature related files (those starting with SIG- with
* an optional [A-Z0-9]{1,3} extension right inside META-INF).
*
* @param name file name
* @return true if the input file name is signature related
*/
public static boolean isSigningRelated(String name) {
name = name.toUpperCase(Locale.ENGLISH);
if (!name.startsWith("META-INF/")) {
return false;
}
name = name.substring(9);
if (name.indexOf('/') != -1) {
return false;
}
if (isBlockOrSF(name) || name.equals("MANIFEST.MF")) {
return true;
} else if (name.startsWith("SIG-")) {
// check filename extension
// see http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures
// for what filename extensions are legal
int extIndex = name.lastIndexOf('.');
if (extIndex != -1) {
String ext = name.substring(extIndex + 1);
// validate length first
if (ext.length() > 3 || ext.length() < 1) {
return false;
}
// then check chars, must be in [a-zA-Z0-9] per the jar spec
for (int index = 0; index < ext.length(); index++) {
char cc = ext.charAt(index);
// chars are promoted to uppercase so skip lowercase checks
if ((cc < 'A' || cc > 'Z') && (cc < '0' || cc > '9')) {
return false;
}
}
}
return true; // no extension is OK
}
return false;
}
/** get digest from cache */
private MessageDigest getDigest(String algorithm)
throws SignatureException {
if (createdDigests == null)
createdDigests = new HashMap<>();
MessageDigest digest = createdDigests.get(algorithm);
if (digest == null) {
try {
digest = MessageDigest.getInstance(algorithm);
createdDigests.put(algorithm, digest);
} catch (NoSuchAlgorithmException nsae) {
// ignore
}
}
return digest;
}
/**
* process the signature block file. Goes through the .SF file
* and adds code signers for each section where the .SF section
* hash was verified against the Manifest section.
*
*
*/
public void process(Hashtable<String, CodeSigner[]> signers,
List<Object> manifestDigests)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
// calls Signature.getInstance() and MessageDigest.getInstance()
// need to use local providers here, see Providers class
Object obj = null;
try {
obj = Providers.startJarVerification();
processImpl(signers, manifestDigests);
} finally {
Providers.stopJarVerification(obj);
}
}
private void processImpl(Hashtable<String, CodeSigner[]> signers,
List<Object> manifestDigests)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
Manifest sf = new Manifest();
sf.read(new ByteArrayInputStream(sfBytes));
String version =
sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION);
if ((version == null) || !(version.equalsIgnoreCase("1.0"))) {
// XXX: should this be an exception?
// for now we just ignore this signature file
return;
}
SignerInfo[] infos = block.verify(sfBytes);
if (infos == null) {
throw new SecurityException("cannot verify signature block file " +
name);
}
CodeSigner[] newSigners = getSigners(infos, block);
// make sure we have something to do all this work for...
if (newSigners == null)
return;
/*
* Look for the latest timestamp in the signature block. If an entry
* has no timestamp, use current time (aka null).
*/
for (CodeSigner s: newSigners) {
if (debug != null) {
debug.println("Gathering timestamp for: " + s.toString());
}
if (s.getTimestamp() == null) {
timestamp = null;
break;
} else if (timestamp == null) {
timestamp = s.getTimestamp();
} else {
if (timestamp.getTimestamp().before(
s.getTimestamp().getTimestamp())) {
timestamp = s.getTimestamp();
}
}
}
Iterator<Map.Entry<String,Attributes>> entries =
sf.getEntries().entrySet().iterator();
// see if we can verify the whole manifest first
boolean manifestSigned = verifyManifestHash(sf, md, manifestDigests);
// verify manifest main attributes
if (!manifestSigned && !verifyManifestMainAttrs(sf, md)) {
throw new SecurityException
("Invalid signature file digest for Manifest main attributes");
}
// go through each section in the signature file
while(entries.hasNext()) {
Map.Entry<String,Attributes> e = entries.next();
String name = e.getKey();
if (manifestSigned ||
(verifySection(e.getValue(), name, md))) {
if (name.startsWith("./"))
name = name.substring(2);
if (name.startsWith("/"))
name = name.substring(1);
updateSigners(newSigners, signers, name);
if (debug != null) {
debug.println("processSignature signed name = "+name);
}
} else if (debug != null) {
debug.println("processSignature unsigned name = "+name);
}
}
// MANIFEST.MF is always regarded as signed
updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
}
/**
* Check if algorithm is permitted using the permittedAlgs Map.
* If the algorithm is not in the map, check against disabled algorithms and
* store the result. If the algorithm is in the map use that result.
* False is returned for weak algorithm, true for good algorithms.
*/
boolean permittedCheck(String key, String algorithm) {
Boolean permitted = permittedAlgs.get(algorithm);
if (permitted == null) {
try {
ConfigurationHolder.JAR_DISABLED_CHECK.permits(algorithm,
new ConstraintsParameters(timestamp));
} catch(GeneralSecurityException e) {
permittedAlgs.put(algorithm, Boolean.FALSE);
permittedAlgs.put(key.toUpperCase(), Boolean.FALSE);
if (debug != null) {
if (e.getMessage() != null) {
debug.println(key + ": " + e.getMessage());
} else {
debug.println(key + ": " + algorithm +
" was disabled, no exception msg given.");
e.printStackTrace();
}
}
return false;
}
permittedAlgs.put(algorithm, Boolean.TRUE);
return true;
}
// Algorithm has already been checked, return the value from map.
return permitted.booleanValue();
}
/**
* With a given header (*-DIGEST*), return a string that lists all the
* algorithms associated with the header.
* If there are none, return "Unknown Algorithm".
*/
String getWeakAlgorithms(String header) {
String w = "";
try {
for (String key : permittedAlgs.keySet()) {
if (key.endsWith(header)) {
w += key.substring(0, key.length() - header.length()) + " ";
}
}
} catch (RuntimeException e) {
w = "Unknown Algorithm(s). Error processing " + header + ". " +
e.getMessage();
}
// This means we have an error in finding weak algorithms, run in
// debug mode to see permittedAlgs map's values.
if (w.length() == 0) {
return "Unknown Algorithm(s)";
}
return w;
}
/**
* See if the whole manifest was signed.
*/
private boolean verifyManifestHash(Manifest sf,
ManifestDigester md,
List<Object> manifestDigests)
throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
// If only weak algorithms are used.
boolean weakAlgs = true;
// If a "*-DIGEST-MANIFEST" entry is found.
boolean validEntry = false;
// go through all the attributes and process *-Digest-Manifest entries
for (Map.Entry<Object,Object> se : mattr.entrySet()) {
String key = se.getKey().toString();
if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST-MANIFEST")) {
// 16 is length of "-Digest-Manifest"
String algorithm = key.substring(0, key.length()-16);
validEntry = true;
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
manifestDigests.add(key);
manifestDigests.add(se.getValue());
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
byte[] computedHash = md.manifestDigest(digest);
byte[] expectedHash =
Base64.getMimeDecoder().decode((String)se.getValue());
if (debug != null) {
debug.println("Signature File: Manifest digest " +
algorithm);
debug.println( " sigfile " + toHex(expectedHash));
debug.println( " computed " + toHex(computedHash));
debug.println();
}
if (MessageDigest.isEqual(computedHash, expectedHash)) {
manifestSigned = true;
} else {
//XXX: we will continue and verify each section
}
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " +
permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms entries used, throw an exception.
if (validEntry && weakAlgs) {
throw new SignatureException("Manifest hash check failed " +
"(DIGEST-MANIFEST). Disabled algorithm(s) used: " +
getWeakAlgorithms("-DIGEST-MANIFEST"));
}
return manifestSigned;
}
private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
// If only weak algorithms are used.
boolean weakAlgs = true;
// If a ATTR_DIGEST entry is found.
boolean validEntry = false;
// go through all the attributes and process
// digest entries for the manifest main attributes
for (Map.Entry<Object,Object> se : mattr.entrySet()) {
String key = se.getKey().toString();
if (key.toUpperCase(Locale.ENGLISH).endsWith(ATTR_DIGEST)) {
String algorithm =
key.substring(0, key.length() - ATTR_DIGEST.length());
validEntry = true;
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
ManifestDigester.Entry mde =
md.get(ManifestDigester.MF_MAIN_ATTRS, false);
byte[] computedHash = mde.digest(digest);
byte[] expectedHash =
Base64.getMimeDecoder().decode((String)se.getValue());
if (debug != null) {
debug.println("Signature File: " +
"Manifest Main Attributes digest " +
digest.getAlgorithm());
debug.println( " sigfile " + toHex(expectedHash));
debug.println( " computed " + toHex(computedHash));
debug.println();
}
if (MessageDigest.isEqual(computedHash, expectedHash)) {
// good
} else {
// we will *not* continue and verify each section
attrsVerified = false;
if (debug != null) {
debug.println("Verification of " +
"Manifest main attributes failed");
debug.println();
}
break;
}
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " +
permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms entries used, throw an exception.
if (validEntry && weakAlgs) {
throw new SignatureException("Manifest Main Attribute check " +
"failed (" + ATTR_DIGEST + "). " +
"Disabled algorithm(s) used: " +
getWeakAlgorithms(ATTR_DIGEST));
}
// this method returns 'true' if either:
// . manifest main attributes were not signed, or
// . manifest main attributes were signed and verified
return attrsVerified;
}
/**
* given the .SF digest header, and the data from the
* section in the manifest, see if the hashes match.
* if not, throw a SecurityException.
*
* @return true if all the -Digest headers verified
* @exception SecurityException if the hash was not equal
*/
private boolean verifySection(Attributes sfAttr,
String name,
ManifestDigester md)
throws IOException, SignatureException
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
// If only weak algorithms are used.
boolean weakAlgs = true;
// If a "*-DIGEST" entry is found.
boolean validEntry = false;
if (mde == null) {
throw new SecurityException(
"no manifest section for signature file entry "+name);
}
if (sfAttr != null) {
//sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
//hex.encodeBuffer(data, System.out);
// go through all the attributes and process *-Digest entries
for (Map.Entry<Object,Object> se : sfAttr.entrySet()) {
String key = se.getKey().toString();
if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST")) {
// 7 is length of "-Digest"
String algorithm = key.substring(0, key.length()-7);
validEntry = true;
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
boolean ok = false;
byte[] expected =
Base64.getMimeDecoder().decode((String)se.getValue());
byte[] computed;
if (workaround) {
computed = mde.digestWorkaround(digest);
} else {
computed = mde.digest(digest);
}
if (debug != null) {
debug.println("Signature Block File: " +
name + " digest=" + digest.getAlgorithm());
debug.println(" expected " + toHex(expected));
debug.println(" computed " + toHex(computed));
debug.println();
}
if (MessageDigest.isEqual(computed, expected)) {
oneDigestVerified = true;
ok = true;
} else {
// attempt to fallback to the workaround
if (!workaround) {
computed = mde.digestWorkaround(digest);
if (MessageDigest.isEqual(computed, expected)) {
if (debug != null) {
debug.println(" re-computed " + toHex(computed));
debug.println();
}
workaround = true;
oneDigestVerified = true;
ok = true;
}
}
}
if (!ok){
throw new SecurityException("invalid " +
digest.getAlgorithm() +
" signature file digest for " + name);
}
}
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " +
permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms entries used, throw an exception.
if (validEntry && weakAlgs) {
throw new SignatureException("Manifest Main Attribute check " +
"failed (DIGEST). Disabled algorithm(s) used: " +
getWeakAlgorithms("DIGEST"));
}
return oneDigestVerified;
}
/**
* Given the PKCS7 block and SignerInfo[], create an array of
* CodeSigner objects. We do this only *once* for a given
* signature block file.
*/
private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block)
throws IOException, NoSuchAlgorithmException, SignatureException,
CertificateException {
ArrayList<CodeSigner> signers = null;
for (int i = 0; i < infos.length; i++) {
SignerInfo info = infos[i];
ArrayList<X509Certificate> chain = info.getCertificateChain(block);
CertPath certChain = certificateFactory.generateCertPath(chain);
if (signers == null) {
signers = new ArrayList<>();
}
// Append the new code signer
signers.add(new CodeSigner(certChain, info.getTimestamp()));
if (debug != null) {
debug.println("Signature Block Certificate: " +
chain.get(0));
}
}
if (signers != null) {
return signers.toArray(new CodeSigner[signers.size()]);
} else {
return null;
}
}
// for the toHex function
private static final char[] hexc =
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
/**
* convert a byte array to a hex string for debugging purposes
* @param data the binary data to be converted to a hex string
* @return an ASCII hex string
*/
static String toHex(byte[] data) {
StringBuilder sb = new StringBuilder(data.length*2);
for (int i=0; i<data.length; i++) {
sb.append(hexc[(data[i] >>4) & 0x0f]);
sb.append(hexc[data[i] & 0x0f]);
}
return sb.toString();
}
// returns true if set contains signer
static boolean contains(CodeSigner[] set, CodeSigner signer)
{
for (int i = 0; i < set.length; i++) {
if (set[i].equals(signer))
return true;
}
return false;
}
// returns true if subset is a subset of set
static boolean isSubSet(CodeSigner[] subset, CodeSigner[] set)
{
// check for the same object
if (set == subset)
return true;
boolean match;
for (int i = 0; i < subset.length; i++) {
if (!contains(set, subset[i]))
return false;
}
return true;
}
/**
* returns true if signer contains exactly the same code signers as
* oldSigner and newSigner, false otherwise. oldSigner
* is allowed to be null.
*/
static boolean matches(CodeSigner[] signers, CodeSigner[] oldSigners,
CodeSigner[] newSigners) {
// special case
if ((oldSigners == null) && (signers == newSigners))
return true;
boolean match;
// make sure all oldSigners are in signers
if ((oldSigners != null) && !isSubSet(oldSigners, signers))
return false;
// make sure all newSigners are in signers
if (!isSubSet(newSigners, signers)) {
return false;
}
// now make sure all the code signers in signers are
// also in oldSigners or newSigners
for (int i = 0; i < signers.length; i++) {
boolean found =
((oldSigners != null) && contains(oldSigners, signers[i])) ||
contains(newSigners, signers[i]);
if (!found)
return false;
}
return true;
}
void updateSigners(CodeSigner[] newSigners,
Hashtable<String, CodeSigner[]> signers, String name) {
CodeSigner[] oldSigners = signers.get(name);
// search through the cache for a match, go in reverse order
// as we are more likely to find a match with the last one
// added to the cache
CodeSigner[] cachedSigners;
for (int i = signerCache.size() - 1; i != -1; i--) {
cachedSigners = signerCache.get(i);
if (matches(cachedSigners, oldSigners, newSigners)) {
signers.put(name, cachedSigners);
return;
}
}
if (oldSigners == null) {
cachedSigners = newSigners;
} else {
cachedSigners =
new CodeSigner[oldSigners.length + newSigners.length];
System.arraycopy(oldSigners, 0, cachedSigners, 0,
oldSigners.length);
System.arraycopy(newSigners, 0, cachedSigners, oldSigners.length,
newSigners.length);
}
signerCache.add(cachedSigners);
signers.put(name, cachedSigners);
}
}

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2012, 2013, 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.*;
import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.util.*;
import sun.security.x509.X509CertImpl;
/**
* A utility class to check if a certificate is untrusted. This is an internal
* mechanism that explicitly marks a certificate as untrusted, normally in the
* case that a certificate is known to be used for malicious reasons.
*
* <b>Attention</b>: This check is NOT meant to replace the standard PKI-defined
* validation check, neither is it used as an alternative to CRL.
*/
public final class UntrustedCertificates {
private static final Debug debug = Debug.getInstance("certpath");
private static final String ALGORITHM_KEY = "Algorithm";
private static final Properties props = new Properties();
private static final String algorithm;
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
"lib/security/blacklisted.certs");
try (FileInputStream fin = new FileInputStream(f)) {
props.load(fin);
// It's said that the fingerprint could contain colons
for (Map.Entry<Object,Object> e: props.entrySet()) {
e.setValue(stripColons(e.getValue()));
}
} catch (IOException fnfe) {
if (debug != null) {
debug.println("Error parsing blacklisted.certs");
}
}
return null;
}
});
algorithm = props.getProperty(ALGORITHM_KEY);
}
private static String stripColons(Object input) {
String s = (String)input;
char[] letters = s.toCharArray();
int pos = 0;
for (int i = 0; i < letters.length; i++) {
if (letters[i] != ':') {
if (i != pos) {
letters[pos] = letters[i];
}
pos++;
}
}
if (pos == letters.length) return s;
else return new String(letters, 0, pos);
}
/**
* Checks if a certificate is untrusted.
*
* @param cert the certificate to check
* @return true if the certificate is untrusted.
*/
public static boolean isUntrusted(X509Certificate cert) {
if (algorithm == null) {
return false;
}
String key;
if (cert instanceof X509CertImpl) {
key = ((X509CertImpl)cert).getFingerprint(algorithm);
} else {
try {
key = new X509CertImpl(cert.getEncoded()).getFingerprint(algorithm);
} catch (CertificateException cee) {
return false;
}
}
return props.containsKey(key);
}
private UntrustedCertificates() {}
}