package sun.security.ec;
import java.util.*;
import java.security.*;
import java.util.regex.Pattern;
import sun.security.util.CurveDB;
import sun.security.util.NamedCurve;
import static sun.security.util.SecurityConstants.PROVIDER_VER;
public final class SunEC extends Provider {
private static final long serialVersionUID = -2279741672933606418L;
private static boolean useFullImplementation = true;
static {
try {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("sunec");
return null;
}
});
} catch (UnsatisfiedLinkError e) {
useFullImplementation = false;
}
}
private static class ProviderService extends Provider.Service {
ProviderService(Provider p, String type, String algo, String cn) {
super(p, type, algo, cn, null, null);
}
ProviderService(Provider p, String type, String algo, String cn,
String[] aliases, HashMap<String, String> attrs) {
super(p, type, algo, cn,
(aliases == null? null : Arrays.asList(aliases)), attrs);
}
@Override
public Object newInstance(Object ctrParamObj)
throws NoSuchAlgorithmException {
String type = getType();
if (ctrParamObj != null) {
throw new InvalidParameterException
("constructorParameter not used with " + type + " engines");
}
String algo = getAlgorithm();
try {
if (type.equals("Signature")) {
boolean inP1363 = algo.endsWith("inP1363Format");
if (inP1363) {
algo = algo.substring(0, algo.length() - 13);
}
if (algo.equals("SHA1withECDSA")) {
return (inP1363? new ECDSASignature.SHA1inP1363Format() :
new ECDSASignature.SHA1());
} else if (algo.equals("SHA224withECDSA")) {
return (inP1363? new ECDSASignature.SHA224inP1363Format() :
new ECDSASignature.SHA224());
} else if (algo.equals("SHA256withECDSA")) {
return (inP1363? new ECDSASignature.SHA256inP1363Format() :
new ECDSASignature.SHA256());
} else if (algo.equals("SHA384withECDSA")) {
return (inP1363? new ECDSASignature.SHA384inP1363Format() :
new ECDSASignature.SHA384());
} else if (algo.equals("SHA512withECDSA")) {
return (inP1363? new ECDSASignature.SHA512inP1363Format() :
new ECDSASignature.SHA512());
} else if (algo.equals("NONEwithECDSA")) {
return (inP1363? new ECDSASignature.RawinP1363Format() :
new ECDSASignature.Raw());
}
} else if (type.equals("KeyFactory")) {
if (algo.equals("EC")) {
return new ECKeyFactory();
} else if (algo.equals("XDH")) {
return new XDHKeyFactory();
} else if (algo.equals("X25519")) {
return new XDHKeyFactory.X25519();
} else if (algo.equals("X448")) {
return new XDHKeyFactory.X448();
}
} else if (type.equals("AlgorithmParameters")) {
if (algo.equals("EC")) {
return new sun.security.util.ECParameters();
}
} else if (type.equals("KeyPairGenerator")) {
if (algo.equals("EC")) {
return new ECKeyPairGenerator();
} else if (algo.equals("XDH")) {
return new XDHKeyPairGenerator();
} else if (algo.equals("X25519")) {
return new XDHKeyPairGenerator.X25519();
} else if (algo.equals("X448")) {
return new XDHKeyPairGenerator.X448();
}
} else if (type.equals("KeyAgreement")) {
if (algo.equals("ECDH")) {
return new ECDHKeyAgreement();
} else if (algo.equals("XDH")) {
return new XDHKeyAgreement();
} else if (algo.equals("X25519")) {
return new XDHKeyAgreement.X25519();
} else if (algo.equals("X448")) {
return new XDHKeyAgreement.X448();
}
}
} catch (Exception ex) {
throw new NoSuchAlgorithmException("Error constructing " +
type + " for " + algo + " using SunEC", ex);
}
throw new ProviderException("No impl for " + algo +
" " + type);
}
}
public SunEC() {
super("SunEC", PROVIDER_VER,
"Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
putEntries(useFullImplementation);
return null;
}
});
}
void putEntries(boolean useFullImplementation) {
HashMap<String, String> ATTRS = new HashMap<>(3);
ATTRS.put("ImplementedIn", "Software");
String ecKeyClasses = "java.security.interfaces.ECPublicKey" +
"|java.security.interfaces.ECPrivateKey";
ATTRS.put("SupportedKeyClasses", ecKeyClasses);
ATTRS.put("KeySize", "256");
putService(new ProviderService(this, "KeyFactory",
"EC", "sun.security.ec.ECKeyFactory",
new String[] { "EllipticCurve" }, ATTRS));
boolean firstCurve = true;
StringBuilder names = new StringBuilder();
Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN);
Collection<? extends NamedCurve> supportedCurves =
CurveDB.getSupportedCurves();
for (NamedCurve namedCurve : supportedCurves) {
if (!firstCurve) {
names.append("|");
} else {
firstCurve = false;
}
names.append("[");
String[] commonNames = nameSplitPattern.split(namedCurve.getName());
for (String commonName : commonNames) {
names.append(commonName.trim());
names.append(",");
}
names.append(namedCurve.getObjectId());
names.append("]");
}
HashMap<String, String> apAttrs = new HashMap<>(ATTRS);
apAttrs.put("SupportedCurves", names.toString());
putService(new ProviderService(this, "AlgorithmParameters",
"EC", "sun.security.util.ECParameters",
new String[] { "EllipticCurve", "1.2.840.10045.2.1", "OID.1.2.840.10045.2.1" },
apAttrs));
putXDHEntries();
if (!useFullImplementation) {
return;
}
putService(new ProviderService(this, "Signature",
"NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw",
null, ATTRS));
putService(new ProviderService(this, "Signature",
"SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1",
new String[] { "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1" },
ATTRS));
putService(new ProviderService(this, "Signature",
"SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224",
new String[] { "1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"},
ATTRS));
putService(new ProviderService(this, "Signature",
"SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256",
new String[] { "1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"},
ATTRS));
putService(new ProviderService(this, "Signature",
"SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384",
new String[] { "1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3" },
ATTRS));
putService(new ProviderService(this, "Signature",
"SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512",
new String[] { "1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4" },
ATTRS));
putService(new ProviderService(this, "Signature",
"NONEwithECDSAinP1363Format",
"sun.security.ec.ECDSASignature$RawinP1363Format"));
putService(new ProviderService(this, "Signature",
"SHA1withECDSAinP1363Format",
"sun.security.ec.ECDSASignature$SHA1inP1363Format"));
putService(new ProviderService(this, "Signature",
"SHA224withECDSAinP1363Format",
"sun.security.ec.ECDSASignature$SHA224inP1363Format"));
putService(new ProviderService(this, "Signature",
"SHA256withECDSAinP1363Format",
"sun.security.ec.ECDSASignature$SHA256inP1363Format"));
putService(new ProviderService(this, "Signature",
"SHA384withECDSAinP1363Format",
"sun.security.ec.ECDSASignature$SHA384inP1363Format"));
putService(new ProviderService(this, "Signature",
"SHA512withECDSAinP1363Format",
"sun.security.ec.ECDSASignature$SHA512inP1363Format"));
putService(new ProviderService(this, "KeyPairGenerator",
"EC", "sun.security.ec.ECKeyPairGenerator",
new String[] { "EllipticCurve" }, ATTRS));
putService(new ProviderService(this, "KeyAgreement",
"ECDH", "sun.security.ec.ECDHKeyAgreement", null, ATTRS));
}
private void putXDHEntries() {
HashMap<String, String> ATTRS = new HashMap<>(1);
ATTRS.put("ImplementedIn", "Software");
putService(new ProviderService(this, "KeyFactory",
"XDH", "sun.security.ec.XDHKeyFactory", null, ATTRS));
putService(new ProviderService(this, "KeyFactory",
"X25519", "sun.security.ec.XDHKeyFactory.X25519",
new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS));
putService(new ProviderService(this, "KeyFactory",
"X448", "sun.security.ec.XDHKeyFactory.X448",
new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS));
putService(new ProviderService(this, "KeyPairGenerator",
"XDH", "sun.security.ec.XDHKeyPairGenerator", null, ATTRS));
putService(new ProviderService(this, "KeyPairGenerator",
"X25519", "sun.security.ec.XDHKeyPairGenerator.X25519",
new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS));
putService(new ProviderService(this, "KeyPairGenerator",
"X448", "sun.security.ec.XDHKeyPairGenerator.X448",
new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS));
putService(new ProviderService(this, "KeyAgreement",
"XDH", "sun.security.ec.XDHKeyAgreement", null, ATTRS));
putService(new ProviderService(this, "KeyAgreement",
"X25519", "sun.security.ec.XDHKeyAgreement.X25519",
new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS));
putService(new ProviderService(this, "KeyAgreement",
"X448", "sun.security.ec.XDHKeyAgreement.X448",
new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS));
}
}