8358171: Additional code coverage for PEM API
Reviewed-by: ascarpino
This commit is contained in:
parent
65fda5c02a
commit
b2e7cda6a0
@ -27,6 +27,7 @@ import javax.crypto.EncryptedPrivateKeyInfo;
|
|||||||
import java.security.DEREncodable;
|
import java.security.DEREncodable;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.PEMRecord;
|
import java.security.PEMRecord;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.interfaces.*;
|
import java.security.interfaces.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -45,7 +46,7 @@ class PEMData {
|
|||||||
KwDdi3cNwu7YYD/QtJ+9+AEBdoqhRANCAASL+REY4vvAI9M3gonaml5K3lRgHq5w
|
KwDdi3cNwu7YYD/QtJ+9+AEBdoqhRANCAASL+REY4vvAI9M3gonaml5K3lRgHq5w
|
||||||
+OO4oO0VNduC44gUN1nrk7/wdNSpL+xXNEX52Dsff+2RD/fop224ANvB
|
+OO4oO0VNduC44gUN1nrk7/wdNSpL+xXNEX52Dsff+2RD/fop224ANvB
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", KeyPair.class);
|
""", KeyPair.class, "SunEC");
|
||||||
|
|
||||||
public static final Entry rsapriv = new Entry("rsapriv",
|
public static final Entry rsapriv = new Entry("rsapriv",
|
||||||
"""
|
"""
|
||||||
@ -65,7 +66,68 @@ class PEMData {
|
|||||||
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
|
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
|
||||||
WqcWcoJqfdLEyBT+
|
WqcWcoJqfdLEyBT+
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", RSAPrivateKey.class);
|
""", RSAPrivateKey.class, "SunRsaSign");
|
||||||
|
|
||||||
|
public static final Entry rsaCrtCoefZeroPriv = new Entry("rsaCrtCoefZeroPriv",
|
||||||
|
"""
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEIwIBAAKCAQEAuZAPiPMlA5R0oOIbxbq+gOmBRcvptIT+0pmG6rZ6H//r7A/Z
|
||||||
|
MRwen0iO2GuhlyUgOk9Fja/TMBrNX99boVDEZtL4oxRTJibdLNjfQqPeFhs3NNvv
|
||||||
|
CJJEGD91Dq/fGbWv1TMZcEywqqYSdERDEA7yluw87I7YZc9kXVBwRw5AedvoXOL/
|
||||||
|
z5yPjK8W7FTCLHSVKiD/X3P3ZX9TmFjTIbRH15Do5sRxsPdrZczYjWdXFXNQEUuF
|
||||||
|
sVFGHFbB/AJiZlGYqMU+hEIErE35sHrKpZYkj9YovYQe0SBJyuROPl8wmz0Cd69s
|
||||||
|
rhg142Qf23RPhclBuCNAQQOkefeCppg4IFFh7QIDAQABAoIBADlKHlm4Q7m2uElB
|
||||||
|
dbSWwqEXNnefjJBUrT3E84/8dXjysNppTDNqzJN9uchcdn+tESWfeshTO97yr2yF
|
||||||
|
j4se3fwm72ed60vwnMFvVYKECBmIHoO90S8yxT49PT0jFDyiSN6IT7bJnpOZAUKP
|
||||||
|
HqtTCheJaQfZ1DqejIx4vKlbX5GfShwPQV0Q7KeKnfxhryhAbM5Y5UT8grQGBQU7
|
||||||
|
aQUZuasQV10APVRaz39VU8/hzBc081LR3O0tjnZcrMAQ7ANsP9Gu3My04cnQ5WBo
|
||||||
|
P8uCCaSPSkrzCvjd9YYkdnwXMbVCfALOa+MxBddMi4IQG0qI28Bpw6dkKziPxage
|
||||||
|
KcAQnAsCgYEA0/CwzUlyrG6f+FF3uAvPVn/jEhWatJb7Me7lkhO3suV92brb1pQo
|
||||||
|
1W1jHdx0OqMuCVfIJ4bXkTwKuvLQGcWJzNWUVh4Tij/ZAV0Ssw2cKbBSCQGNIFsx
|
||||||
|
Ux0V9tDSYJsEdk+Y5grloDNJokYYCCpF5bz/6QYmX+t3yzjyVSvcNeMCgYEA4COU
|
||||||
|
ezUXKLSWD+jJZXpS5yopB7oXAg7mmonlc1DRuaIxspwBrbXPLQ/neN8Sefpz9Nxn
|
||||||
|
4ksPxGbLnJh0wGCnxSu0Qfn4eNVSsulag4IQmbCO2UBsdXNCJB5KlDpRlVhvvviH
|
||||||
|
Zpz2Dkdx+itLf1EV841MCtPAHZJwrs6i6JntEe8CgYEAgJYdjs+rJXcQ04YKDr4L
|
||||||
|
k72PtR8qd7rKuObqnhAcegvGqV03mB7YD3WIl0tzsUfj3INHysOC8njtQbOkEp7J
|
||||||
|
Fl/W2dDxpgVK0gr4F26AesKhYxlv2Fu7t2OEOfVETpx+vpFYgOnHm8TCPhQs7HdJ
|
||||||
|
ZTOgSG8UxUmFquToEkjEGGUCgYB6AMP8wKxHeuzH4iVl+EySCa/lxdRqSWQasH7V
|
||||||
|
4yMVkYTNvP9o57LKy4Jql7n97Wca3LIrSkJd3LpuFcpPQQ1xVNW8p+0pEK0AN+cN
|
||||||
|
+ElC7wkCln+y+rcA5AAiaRApY8cHw04oe72vjhIrY0+oEKILPVkr95D2R9TQQigI
|
||||||
|
xmh1vwIBAA==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
""", RSAPrivateKey.class, "SunRsaSign");
|
||||||
|
|
||||||
|
public static final Entry rsapsspriv = new Entry("rsapsspriv",
|
||||||
|
"""
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEAn3qFQtvj9JVqVPRh
|
||||||
|
mMMRyT17GiUY+NWOwUHx5bHqfhlHJoCllctSU/YXzrH4Da1w7sSeaMmAKYMW4X5k
|
||||||
|
rn9hnKOhgHnm2nkZBaVNQeyrseuDnfwWtLXjnj8rEKpgf9UPRUeXGRSoAb1qpwBf
|
||||||
|
epFtLSKZrzswZY2u2UEUGJERABi6Qp+cIZ8uXzBkIsMgrhb50xsdysZ9+qq95z0i
|
||||||
|
N1vh/V+Yi2fYpSYVDE8aMWdpvs0oWGvoLQjRgElJx/SknndAfLD42HPYZyyXevyJ
|
||||||
|
RgUf+NP0V7c+UtE7m7pgMs1hhxHSmUNdfH9GnOSg9m3+L3WqhaNNWB4aKMqFyhlM
|
||||||
|
EsAuawIDAQABAoIBAAMJ9yXIgeYEaN54j67fsg7nJIQ228HLc/5xGWvFQaYofidu
|
||||||
|
K87twm0GKKWlf4gR24U5QEQtPst2YNu9fav+PRJv4yEgcYqNOdxWg4veN4Fa7wr2
|
||||||
|
JZ/zmARJHjLMRFgl67YSwKmCMBdkZXa24PA5et6cJQM7+gFIELe5b+lt7j3VsxQ7
|
||||||
|
JpTJyp3I73lXcJrzcb/OCTxobFPLtkVSgKUNwae26xlNqXX4fQfLp99LHGnkmG3k
|
||||||
|
Wlzjs6dUi4fl4yLAJYMxEwxQbSbmY66ZKnM4SkT/YHx67gyJw2CMRp4FQDg94Sor
|
||||||
|
0IDDKiSMGzcjuCuUl27/qTuv+iMgCqNB7CSPXtECgYEAvqN8ZuZXeUKz4tn6wxJk
|
||||||
|
k1utCl3pSM5PLMF4J43uvX49HF1i3svXrwxzJqug6kPXvB7cuB6U2DFIM3lh2jNE
|
||||||
|
u2w0U/5zVz2yEI9EaRjnOXePLsSWjOiC+5MGTafJWy5vZ8+zaWL9tjtUH5hsg1cB
|
||||||
|
ZMlXtWrI+AmAUAv6FFDZaHECgYEA1igXzRMGgXAT+YX0wdZQcRMy9jD5WIYIiCex
|
||||||
|
6/WRE2LDM855ZBwTU5gyqZC2MWC3yn1ASDraxKdH1m3872Q0NVJfsOaLvBk1HuPk
|
||||||
|
dlSHRKO2GeO9m5/YzrZm9jpGs0IH6DKOah/t0aCd2CFxt6qef2wOUmXTCK6tyCXN
|
||||||
|
EiUmEpsCgYAMue85E1Ftl+VYVILn+Ndb+ve/RGupX5RrgXLa+R+h6MZ9mUJbazI3
|
||||||
|
zlX1k+mHGgZR2aGUbP40vH18ajL9FQUWme+YV9ktTsIPVvETLwVokbGuRpNiTrdH
|
||||||
|
whXeoz/O5Xesb3Ijq+cR/j3sagl8bxd5ufMv+jP2UvQM4+/K4WbSEQKBgGuZeVvw
|
||||||
|
UzR1u5ODWpaJt6EYpGJN+PohXegLCbokh9/Vn35IH3XNJWi677mCnAfzMGTsyX+B
|
||||||
|
Eqn74nw6hvtAvXqNCMc5DrxTbf03Q3KwxcYW+0fGxV2L0sMJonHUlfE7G/3uaN+p
|
||||||
|
azQIH0aYhypg74HWKNv9jSqvmWEWnRKg16BBAoGAGLAqCRCP8wxqRVZZjhUJ+5JN
|
||||||
|
b6PrykDxCKhlA6JqZKuCYzvXhLABq/7miNDg0CmRREl+yKXlkEoFl4g9LtP7wfjX
|
||||||
|
n4us/WNmh+GPZYxlCJSNRTjgk7pm5TjVH5YWURDEnjIHZ7yxbAFlvNUhI1mF5g97
|
||||||
|
KVcB4fjBitP1h8P+MoY=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
""", RSAPrivateKey.class, "SunRsaSign");
|
||||||
|
|
||||||
public static final Entry rsaprivbc = new Entry("rsaprivbc",
|
public static final Entry rsaprivbc = new Entry("rsaprivbc",
|
||||||
"""
|
"""
|
||||||
@ -85,14 +147,14 @@ class PEMData {
|
|||||||
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
|
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
|
||||||
WqcWcoJqfdLEyBT+
|
WqcWcoJqfdLEyBT+
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", RSAPrivateKey.class);
|
""", RSAPrivateKey.class, "SunRsaSign");
|
||||||
|
|
||||||
public static final Entry ec25519priv = new Entry("ed25519priv",
|
public static final Entry ec25519priv = new Entry("ed25519priv",
|
||||||
"""
|
"""
|
||||||
-----BEGIN PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
|
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", EdECPrivateKey.class);
|
""", EdECPrivateKey.class, "SunEC");
|
||||||
|
|
||||||
public static final Entry rsapub = new Entry("rsapub",
|
public static final Entry rsapub = new Entry("rsapub",
|
||||||
"""
|
"""
|
||||||
@ -102,7 +164,20 @@ class PEMData {
|
|||||||
MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h
|
MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h
|
||||||
XCYEHZS1cqd8wokFPwIDAQAB
|
XCYEHZS1cqd8wokFPwIDAQAB
|
||||||
-----END PUBLIC KEY-----
|
-----END PUBLIC KEY-----
|
||||||
""", RSAPublicKey.class);
|
""", RSAPublicKey.class, "SunRsaSign");
|
||||||
|
|
||||||
|
public static final Entry rsapsspub = new Entry("rsapsspub",
|
||||||
|
"""
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBAJ96hULb4/SValT0YZjDEck9
|
||||||
|
exolGPjVjsFB8eWx6n4ZRyaApZXLUlP2F86x+A2tcO7EnmjJgCmDFuF+ZK5/YZyj
|
||||||
|
oYB55tp5GQWlTUHsq7Hrg538FrS1454/KxCqYH/VD0VHlxkUqAG9aqcAX3qRbS0i
|
||||||
|
ma87MGWNrtlBFBiREQAYukKfnCGfLl8wZCLDIK4W+dMbHcrGffqqvec9Ijdb4f1f
|
||||||
|
mItn2KUmFQxPGjFnab7NKFhr6C0I0YBJScf0pJ53QHyw+Nhz2Gcsl3r8iUYFH/jT
|
||||||
|
9Fe3PlLRO5u6YDLNYYcR0plDXXx/RpzkoPZt/i91qoWjTVgeGijKhcoZTBLALmsC
|
||||||
|
AwEAAQ==
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
""", RSAPublicKey.class, "SunRsaSign");
|
||||||
|
|
||||||
public static final Entry rsapubbc = new Entry("rsapubbc",
|
public static final Entry rsapubbc = new Entry("rsapubbc",
|
||||||
"""
|
"""
|
||||||
@ -112,14 +187,14 @@ class PEMData {
|
|||||||
MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h
|
MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h
|
||||||
XCYEHZS1cqd8wokFPwIDAQAB
|
XCYEHZS1cqd8wokFPwIDAQAB
|
||||||
-----END PUBLIC KEY-----
|
-----END PUBLIC KEY-----
|
||||||
""", RSAPublicKey.class);
|
""", RSAPublicKey.class, "SunRsaSign");
|
||||||
|
|
||||||
public static final Entry ecsecp256pub = new Entry("ecsecp256pub", """
|
public static final Entry ecsecp256pub = new Entry("ecsecp256pub", """
|
||||||
-----BEGIN PUBLIC KEY-----
|
-----BEGIN PUBLIC KEY-----
|
||||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/kRGOL7wCPTN4KJ2ppeSt5UYB6u
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/kRGOL7wCPTN4KJ2ppeSt5UYB6u
|
||||||
cPjjuKDtFTXbguOIFDdZ65O/8HTUqS/sVzRF+dg7H3/tkQ/36KdtuADbwQ==
|
cPjjuKDtFTXbguOIFDdZ65O/8HTUqS/sVzRF+dg7H3/tkQ/36KdtuADbwQ==
|
||||||
-----END PUBLIC KEY-----
|
-----END PUBLIC KEY-----
|
||||||
""", ECPublicKey.class);
|
""", ECPublicKey.class, "SunEC");
|
||||||
|
|
||||||
// EC key with explicit parameters -- Not currently supported by SunEC
|
// EC key with explicit parameters -- Not currently supported by SunEC
|
||||||
public static final String pubec_explicit = """
|
public static final String pubec_explicit = """
|
||||||
@ -152,7 +227,7 @@ class PEMData {
|
|||||||
P4c4mySRy5N3plFQUp3pIB7wqshi1t6hkdg7gRGjMtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarb
|
P4c4mySRy5N3plFQUp3pIB7wqshi1t6hkdg7gRGjMtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarb
|
||||||
D6D4yRY1hWHluiuOtzhxuueCuf9hXCYEHZS1cqd8wokFPwIDAQAB
|
D6D4yRY1hWHluiuOtzhxuueCuf9hXCYEHZS1cqd8wokFPwIDAQAB
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", KeyPair.class);
|
""", KeyPair.class, "SunRsaSign");
|
||||||
|
|
||||||
public static final Entry oasrfc8410 = new Entry("oasrfc8410",
|
public static final Entry oasrfc8410 = new Entry("oasrfc8410",
|
||||||
"""
|
"""
|
||||||
@ -161,7 +236,24 @@ class PEMData {
|
|||||||
oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB
|
oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB
|
||||||
Z9w7lshQhqowtrbLDFw4rXAxZuE=
|
Z9w7lshQhqowtrbLDFw4rXAxZuE=
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", KeyPair.class);
|
""", KeyPair.class, "SunEC");
|
||||||
|
|
||||||
|
public static final Entry oasxdh = new Entry("oasxdh",
|
||||||
|
"""
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MFECAQEwBQYDK2VuBCIEIIrMS7w5YxuBTyPFiaFvp6ILiGET7wY9ybk7Qqhe3hSq
|
||||||
|
gSEAB7ODPxRePrPnJMaj3f47blVx6c5bfxcllQzLp4bW5x4=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
""", KeyPair.class, "SunEC");
|
||||||
|
|
||||||
|
public static final Entry oasec = new Entry("oasec",
|
||||||
|
"""
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGFAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBCcwJQIBAQQgkGEVbZE1yAiO11Ya
|
||||||
|
eepcrBQL+HpVE4fy0V6jbpJcmkiBQgAERCqYYmN9uNT9Z1O2Z2VC3Zag9eUAhz7G
|
||||||
|
p8DqC21VrIgpqVQ4BrcWsieNg9fSd4N2hgfMpk9PCQwJQ8ifCMiBVQ==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
""", KeyPair.class, "SunEC");
|
||||||
|
|
||||||
public static final Entry rsaOpenSSL = new Entry("rsaOpenSSL",
|
public static final Entry rsaOpenSSL = new Entry("rsaOpenSSL",
|
||||||
"""
|
"""
|
||||||
@ -192,7 +284,7 @@ class PEMData {
|
|||||||
EcgIOtkvoTrJ9Cquvuj+O7/d2yNoH0SZQ4IYJKq47/Z4kKhwXzJnBCCCBKgkjfub
|
EcgIOtkvoTrJ9Cquvuj+O7/d2yNoH0SZQ4IYJKq47/Z4kKhwXzJnBCCCBKgkjfub
|
||||||
RTQSNnSEgTaBD29l7FrhNRHX9lIKFZ23caCTBS6o3q3+KgPbq7ao
|
RTQSNnSEgTaBD29l7FrhNRHX9lIKFZ23caCTBS6o3q3+KgPbq7ao
|
||||||
-----END RSA PRIVATE KEY-----
|
-----END RSA PRIVATE KEY-----
|
||||||
""", RSAPrivateKey.class);
|
""", RSAPrivateKey.class, "SunRsaSign");
|
||||||
|
|
||||||
static final Entry ed25519ep8 = new Entry("ed25519ep8",
|
static final Entry ed25519ep8 = new Entry("ed25519ep8",
|
||||||
"""
|
"""
|
||||||
@ -202,11 +294,11 @@ class PEMData {
|
|||||||
vdMyi46+Dw7cOjwEQLtx5ME0NOOo7vlCGm3H/4j+Tf5UXrMb1UrkPjqc8OiLbC0n
|
vdMyi46+Dw7cOjwEQLtx5ME0NOOo7vlCGm3H/4j+Tf5UXrMb1UrkPjqc8OiLbC0n
|
||||||
IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo=
|
IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo=
|
||||||
-----END ENCRYPTED PRIVATE KEY-----
|
-----END ENCRYPTED PRIVATE KEY-----
|
||||||
""", EdECPrivateKey.class, "fish".toCharArray());
|
""", EdECPrivateKey.class, "SunEC", "fish".toCharArray());
|
||||||
|
|
||||||
// This is not meant to be decrypted and to stay as an EKPI
|
// This is not meant to be decrypted and to stay as an EKPI
|
||||||
static final Entry ed25519ekpi = new Entry("ed25519ekpi",
|
static final Entry ed25519ekpi = new Entry("ed25519ekpi",
|
||||||
ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, null);
|
ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, "SunEC", null);
|
||||||
|
|
||||||
static final Entry rsaCert = new Entry("rsaCert",
|
static final Entry rsaCert = new Entry("rsaCert",
|
||||||
"""
|
"""
|
||||||
@ -237,7 +329,7 @@ class PEMData {
|
|||||||
8gOYV33zkPhziWJt4uFMFIi7N2DLEk5UVZv1KTLZlfPl55DRs7j/Sb4vKHpB17AO
|
8gOYV33zkPhziWJt4uFMFIi7N2DLEk5UVZv1KTLZlfPl55DRs7j/Sb4vKHpB17AO
|
||||||
meVknxVvifDVY0TIz57t28Accsk6ClBCxNPluPU/8YLGAZJYsdDXjGcndQ13s5G7
|
meVknxVvifDVY0TIz57t28Accsk6ClBCxNPluPU/8YLGAZJYsdDXjGcndQ13s5G7
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
""", X509Certificate.class);
|
""", X509Certificate.class, "SUN");
|
||||||
|
|
||||||
static final Entry ecCert = new Entry("ecCert",
|
static final Entry ecCert = new Entry("ecCert",
|
||||||
"""
|
"""
|
||||||
@ -249,7 +341,68 @@ class PEMData {
|
|||||||
lU3G9QAwCgYIKoZIzj0EAwIDSAAwRQIgMwYld7aBzkcRt9mn27YOed5+n0xN1y8Q
|
lU3G9QAwCgYIKoZIzj0EAwIDSAAwRQIgMwYld7aBzkcRt9mn27YOed5+n0xN1y8Q
|
||||||
VEcFjLI/tBYCIQDU3szDZ/PK2mUZwtgQxLqHdh+f1JY0UwQS6M8QUvoDHw==
|
VEcFjLI/tBYCIQDU3szDZ/PK2mUZwtgQxLqHdh+f1JY0UwQS6M8QUvoDHw==
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
""", X509Certificate.class);
|
""", X509Certificate.class, "SUN");
|
||||||
|
|
||||||
|
private static final Entry rsaCrl = new Entry("rsaCrl",
|
||||||
|
"""
|
||||||
|
-----BEGIN X509 CRL-----
|
||||||
|
MIIBRTCBrwIBATANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQGEwJVUzEaMBgGA1UE
|
||||||
|
ChMRVGVzdCBDZXJ0aWZpY2F0ZXMxITAfBgNVBAMTGEJhc2ljIEhUVFAgVVJJIFBl
|
||||||
|
ZXIgMSBDQRcNMDUwNjAzMjE0NTQ3WhcNMTUwNjAxMjE0NTQ3WqAvMC0wHwYDVR0j
|
||||||
|
BBgwFoAUa+bxcvx1zVdUhvIEd9hcfbmFdw4wCgYDVR0UBAMCAQEwDQYJKoZIhvcN
|
||||||
|
AQEFBQADgYEAZ+21yt1pJn2FU6vBwpFtAKVeBCCCqJVFiRxT84XbUw0BpLrCFvlk
|
||||||
|
FOo6tC95aoV7vPGwOEyUNbKJJOCzLliIwV1PPfgZQV20xohSIPISHdUjmlyttglv
|
||||||
|
AuEvltGnbP7ENxw18HxvM20XmHz+akuFu6npI6MkBjfoxvlq1bcdTrI=
|
||||||
|
-----END X509 CRL-----
|
||||||
|
""", X509CRL.class, "SUN");
|
||||||
|
|
||||||
|
// Few random manipulated Base64 characters in PEM content
|
||||||
|
private static final Entry invalidDer = new Entry("invalidDER", """
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIICeAIBADANBhkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOtjMnCzPy4jCeZb
|
||||||
|
OdOvmvU3jl7+cvPFgL5MfqDCM5a8yI0yImg/hzibJJHLk3emUVBSnekgHvCqyGLW
|
||||||
|
3qGR2DuBEaMy0mkg8hfKcSpHLaYjDYaspO27d2qtb6d1qtsPoPjJFjWFYeW6K463
|
||||||
|
OHG654K5/2FcJgQdlLVyp3zCiQU/AgMBAAECgYEAwNkDkTv5rlX8nWLuLJV5kh/T
|
||||||
|
H9a93SRZxw8qy5Bv7bZ7ZNfHP7uUkHbi7iPojKWRhwo43692SdzR0dCSk7LGgN9q
|
||||||
|
CYvndsYR6gifVGBi0WF+St4+NdtcQ3VlNdsojy2BdIx0oC+r7i3bn+zc968O/kI+
|
||||||
|
EgdgrMcjjFqyx6tMHpECQQD8TYPKGHyN7Jdy28llCoUX/sL/yZ2vIi5mnDAFE5ae
|
||||||
|
KZQSkNAXG+8i9Qbs/Wdd5S3oZDqu+6DBn9gib80pYY05AkEA7tY59Oy8ka7nBlGP
|
||||||
|
g6Wo1usF2bKqk8vjko9ioZQay7f86aB10QFcAjCr+cCUm16Lc9DwzWl02nNggRZa
|
||||||
|
Jz8eNwJBAO+1zfLjFOPb14F/JHdlaVKE8EwKCFDuztsapd0M4Vtf8Zk6ERsDpU63
|
||||||
|
Ml9T2zOwnM9g+whpdjDAZ59ATdJ1JrECQQDReJQ2SxeL0lGPCiOLu9RcQp7L81aF
|
||||||
|
79G1bgp8WlAyEjlAkloiqEWRKiz7DDuKFR7Lwhognng9S+n87aS+PS57AkBh75t8
|
||||||
|
6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob
|
||||||
|
WqcWcoJqfdLEyBT+
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
""", DEREncodable.class, null);
|
||||||
|
|
||||||
|
private static final Entry invalidPEM = new Entry("invalidPEM", """
|
||||||
|
-----BEGIN INVALID PEM-----
|
||||||
|
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2
|
||||||
|
GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8
|
||||||
|
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
|
||||||
|
""", DEREncodable.class, null);
|
||||||
|
|
||||||
|
private static final Entry invalidHeader = new Entry("invalidHeader", """
|
||||||
|
---BEGIN PRIVATE KEY---
|
||||||
|
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
""", DEREncodable.class, null);
|
||||||
|
|
||||||
|
private static final Entry invalidFooter = new Entry("invalidFooter", """
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I
|
||||||
|
---END PRIVATE KEY---
|
||||||
|
""", DEREncodable.class, null);
|
||||||
|
|
||||||
|
private static final Entry incorrectFooter = new Entry("incorrectFooter", """
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2
|
||||||
|
GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8
|
||||||
|
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
|
||||||
|
8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM=
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
""", DEREncodable.class, null);
|
||||||
|
|
||||||
// EC cert with explicit parameters -- Not currently supported by SunEC
|
// EC cert with explicit parameters -- Not currently supported by SunEC
|
||||||
static final String ecCertEX = """
|
static final String ecCertEX = """
|
||||||
@ -280,7 +433,7 @@ class PEMData {
|
|||||||
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
|
8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM
|
||||||
8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM=
|
8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM=
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""", KeyPair.class);
|
""", KeyPair.class, "SunEC");
|
||||||
|
|
||||||
public static final Entry ecCSR = new Entry("ecCSR",
|
public static final Entry ecCSR = new Entry("ecCSR",
|
||||||
"""
|
"""
|
||||||
@ -297,7 +450,7 @@ class PEMData {
|
|||||||
MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR
|
MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR
|
||||||
kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW
|
kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW
|
||||||
-----END CERTIFICATE REQUEST-----
|
-----END CERTIFICATE REQUEST-----
|
||||||
""", PEMRecord.class);
|
""", PEMRecord.class, "SunEC");
|
||||||
|
|
||||||
public static final String preData = "TEXT BLAH TEXT BLAH" +
|
public static final String preData = "TEXT BLAH TEXT BLAH" +
|
||||||
System.lineSeparator();
|
System.lineSeparator();
|
||||||
@ -318,39 +471,41 @@ class PEMData {
|
|||||||
MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR
|
MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR
|
||||||
kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW
|
kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW
|
||||||
-----END CERTIFICATE REQUEST-----
|
-----END CERTIFICATE REQUEST-----
|
||||||
""" + postData, PEMRecord.class);
|
""" + postData, PEMRecord.class, "SunEC");
|
||||||
|
|
||||||
final static Pattern CR = Pattern.compile("\r");
|
final static Pattern CR = Pattern.compile("\r");
|
||||||
final static Pattern LF = Pattern.compile("\n");
|
final static Pattern LF = Pattern.compile("\n");
|
||||||
final static Pattern LSDEFAULT = Pattern.compile(System.lineSeparator());
|
final static Pattern LSDEFAULT = Pattern.compile(System.lineSeparator());
|
||||||
|
|
||||||
|
|
||||||
public record Entry(String name, String pem, Class clazz, char[] password,
|
public record Entry(String name, String pem, Class clazz, String provider, char[] password,
|
||||||
byte[] der) {
|
byte[] der) {
|
||||||
|
|
||||||
public Entry(String name, String pem, Class clazz, char[] password,
|
public Entry(String name, String pem, Class clazz, String provider, char[] password,
|
||||||
byte[] der) {
|
byte[] der) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.pem = pem;
|
this.pem = pem;
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
|
this.provider = provider;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
if (pem != null && pem.length() > 0) {
|
if (pem != null && pem.length() > 0 &&
|
||||||
|
!name.contains("incorrect") && !name.contains("invalid")) {
|
||||||
String[] pemtext = pem.split("-----");
|
String[] pemtext = pem.split("-----");
|
||||||
this.der = Base64.getMimeDecoder().decode(pemtext[2]);
|
this.der = Base64.getMimeDecoder().decode(pemtext[2]);
|
||||||
} else {
|
} else {
|
||||||
this.der = null;
|
this.der = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Entry(String name, String pem, Class clazz, char[] password) {
|
Entry(String name, String pem, Class clazz, String provider, char[] password) {
|
||||||
this(name, pem, clazz, password, null);
|
this(name, pem, clazz, provider, password, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry(String name, String pem, Class clazz) {
|
Entry(String name, String pem, Class clazz, String provider) {
|
||||||
this(name, pem, clazz, null, null);
|
this(name, pem, clazz, provider, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entry newClass(String name, Class c) {
|
public Entry newClass(String name, Class c) {
|
||||||
return new Entry(name, pem, c, password);
|
return new Entry(name, pem, c, provider, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entry newClass(Class c) {
|
public Entry newClass(Class c) {
|
||||||
@ -360,20 +515,20 @@ class PEMData {
|
|||||||
Entry makeCRLF(String name) {
|
Entry makeCRLF(String name) {
|
||||||
return new Entry(name,
|
return new Entry(name,
|
||||||
Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r\n"),
|
Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r\n"),
|
||||||
clazz, password());
|
clazz, provider, password());
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry makeCR(String name) {
|
Entry makeCR(String name) {
|
||||||
return new Entry(name,
|
return new Entry(name,
|
||||||
Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r"),
|
Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r"),
|
||||||
clazz, password());
|
clazz, provider, password());
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry makeNoCRLF(String name) {
|
Entry makeNoCRLF(String name) {
|
||||||
return new Entry(name,
|
return new Entry(name,
|
||||||
LF.matcher(CR.matcher(pem).replaceAll("")).
|
LF.matcher(CR.matcher(pem).replaceAll("")).
|
||||||
replaceAll(""),
|
replaceAll(""),
|
||||||
clazz, password());
|
clazz, provider, password());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,10 +556,12 @@ class PEMData {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
pubList.add(rsapub);
|
pubList.add(rsapub);
|
||||||
|
pubList.add(rsapsspub);
|
||||||
pubList.add(rsapubbc);
|
pubList.add(rsapubbc);
|
||||||
pubList.add(ecsecp256pub.makeCR("ecsecp256pub-r"));
|
pubList.add(ecsecp256pub.makeCR("ecsecp256pub-r"));
|
||||||
pubList.add(ecsecp256pub.makeCRLF("ecsecp256pub-rn"));
|
pubList.add(ecsecp256pub.makeCRLF("ecsecp256pub-rn"));
|
||||||
privList.add(rsapriv);
|
privList.add(rsapriv);
|
||||||
|
privList.add(rsapsspriv);
|
||||||
privList.add(rsaprivbc);
|
privList.add(rsaprivbc);
|
||||||
privList.add(ecsecp256);
|
privList.add(ecsecp256);
|
||||||
privList.add(ecsecp384);
|
privList.add(ecsecp384);
|
||||||
@ -413,9 +570,12 @@ class PEMData {
|
|||||||
privList.add(rsaOpenSSL);
|
privList.add(rsaOpenSSL);
|
||||||
oasList.add(oasrfc8410);
|
oasList.add(oasrfc8410);
|
||||||
oasList.add(oasbcpem);
|
oasList.add(oasbcpem);
|
||||||
|
oasList.add(oasec);
|
||||||
|
oasList.add(oasxdh);
|
||||||
|
|
||||||
certList.add(rsaCert);
|
certList.add(rsaCert);
|
||||||
certList.add(ecCert);
|
certList.add(ecCert);
|
||||||
|
certList.add(rsaCrl);
|
||||||
|
|
||||||
entryList.addAll(pubList);
|
entryList.addAll(pubList);
|
||||||
entryList.addAll(privList);
|
entryList.addAll(privList);
|
||||||
@ -429,6 +589,11 @@ class PEMData {
|
|||||||
|
|
||||||
failureEntryList.add(new Entry("emptyPEM", "", DEREncodable.class, null));
|
failureEntryList.add(new Entry("emptyPEM", "", DEREncodable.class, null));
|
||||||
failureEntryList.add(new Entry("nullPEM", null, DEREncodable.class, null));
|
failureEntryList.add(new Entry("nullPEM", null, DEREncodable.class, null));
|
||||||
|
failureEntryList.add(incorrectFooter);
|
||||||
|
failureEntryList.add(invalidPEM);
|
||||||
|
failureEntryList.add(invalidDer);
|
||||||
|
failureEntryList.add(invalidHeader);
|
||||||
|
failureEntryList.add(invalidFooter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkResults(PEMData.Entry entry, String result) {
|
static void checkResults(PEMData.Entry entry, String result) {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8298420
|
* @bug 8298420
|
||||||
|
* @library /test/lib
|
||||||
* @modules java.base/sun.security.pkcs
|
* @modules java.base/sun.security.pkcs
|
||||||
* java.base/sun.security.util
|
* java.base/sun.security.util
|
||||||
* @summary Testing basic PEM API decoding
|
* @summary Testing basic PEM API decoding
|
||||||
@ -37,23 +38,27 @@ import java.io.*;
|
|||||||
import java.lang.Class;
|
import java.lang.Class;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
import java.security.cert.CertificateEncodingException;
|
||||||
import java.security.cert.X509CRL;
|
import java.security.cert.X509CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.interfaces.*;
|
import java.security.interfaces.*;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.*;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
import sun.security.pkcs.PKCS8Key;
|
||||||
import sun.security.util.Pem;
|
import sun.security.util.Pem;
|
||||||
|
|
||||||
public class PEMDecoderTest {
|
public class PEMDecoderTest {
|
||||||
|
|
||||||
static HexFormat hex = HexFormat.of();
|
static HexFormat hex = HexFormat.of();
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws Exception {
|
||||||
System.out.println("Decoder test:");
|
System.out.println("Decoder test:");
|
||||||
PEMData.entryList.forEach(PEMDecoderTest::test);
|
PEMData.entryList.forEach(entry -> test(entry, false));
|
||||||
|
System.out.println("Decoder test withFactory:");
|
||||||
|
PEMData.entryList.forEach(entry -> test(entry, true));
|
||||||
System.out.println("Decoder test returning DEREncodable class:");
|
System.out.println("Decoder test returning DEREncodable class:");
|
||||||
PEMData.entryList.forEach(entry -> test(entry, DEREncodable.class));
|
PEMData.entryList.forEach(entry -> test(entry, DEREncodable.class));
|
||||||
System.out.println("Decoder test with encrypted PEM:");
|
System.out.println("Decoder test with encrypted PEM:");
|
||||||
@ -95,7 +100,11 @@ public class PEMDecoderTest {
|
|||||||
|
|
||||||
System.out.println("Check a Signature/Verify op is successful:");
|
System.out.println("Check a Signature/Verify op is successful:");
|
||||||
PEMData.privList.forEach(PEMDecoderTest::testSignature);
|
PEMData.privList.forEach(PEMDecoderTest::testSignature);
|
||||||
PEMData.oasList.forEach(PEMDecoderTest::testSignature);
|
PEMData.oasList.stream().filter(e -> !e.name().endsWith("xdh"))
|
||||||
|
.forEach(PEMDecoderTest::testSignature);
|
||||||
|
|
||||||
|
System.out.println("Checking if decode() returns a PKCS8Key and can generate a pub");
|
||||||
|
PEMData.oasList.forEach(PEMDecoderTest::testPKCS8Key);
|
||||||
|
|
||||||
System.out.println("Checking if ecCSR:");
|
System.out.println("Checking if ecCSR:");
|
||||||
test(PEMData.ecCSR);
|
test(PEMData.ecCSR);
|
||||||
@ -182,6 +191,10 @@ public class PEMDecoderTest {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError("error getting key", e);
|
throw new AssertionError("error getting key", e);
|
||||||
}
|
}
|
||||||
|
testCertTypeConverter(PEMData.ecCert);
|
||||||
|
|
||||||
|
System.out.println("Decoder test testCoefZero:");
|
||||||
|
testCoefZero(PEMData.rsaCrtCoefZeroPriv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testInputStream() throws IOException {
|
static void testInputStream() throws IOException {
|
||||||
@ -231,6 +244,24 @@ public class PEMDecoderTest {
|
|||||||
throw new AssertionError("Failed");
|
throw new AssertionError("Failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test that X509 CERTIFICATE is converted to CERTIFICATE in PEM
|
||||||
|
static void testCertTypeConverter(PEMData.Entry entry) throws CertificateEncodingException {
|
||||||
|
String certPem = entry.pem().replace("CERTIFICATE", "X509 CERTIFICATE");
|
||||||
|
Asserts.assertEqualsByteArray(entry.der(),
|
||||||
|
PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded());
|
||||||
|
|
||||||
|
certPem = entry.pem().replace("CERTIFICATE", "X.509 CERTIFICATE");
|
||||||
|
Asserts.assertEqualsByteArray(entry.der(),
|
||||||
|
PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded());
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that when the crtCoeff is zero, the key is decoded but only the modulus and private
|
||||||
|
// exponent are used resulting in a different der
|
||||||
|
static void testCoefZero(PEMData.Entry entry) {
|
||||||
|
RSAPrivateKey decoded = PEMDecoder.of().decode(entry.pem(), RSAPrivateKey.class);
|
||||||
|
Asserts.assertNotEqualsByteArray(decoded.getEncoded(), entry.der());
|
||||||
|
}
|
||||||
|
|
||||||
static void testPEMRecord(PEMData.Entry entry) {
|
static void testPEMRecord(PEMData.Entry entry) {
|
||||||
PEMRecord r = PEMDecoder.of().decode(entry.pem(), PEMRecord.class);
|
PEMRecord r = PEMDecoder.of().decode(entry.pem(), PEMRecord.class);
|
||||||
String expected = entry.pem().split("-----")[2].replace(System.lineSeparator(), "");
|
String expected = entry.pem().split("-----")[2].replace(System.lineSeparator(), "");
|
||||||
@ -333,13 +364,26 @@ public class PEMDecoderTest {
|
|||||||
|
|
||||||
// Change the Entry to use the given class as the expected class returned
|
// Change the Entry to use the given class as the expected class returned
|
||||||
static DEREncodable test(PEMData.Entry entry, Class c) {
|
static DEREncodable test(PEMData.Entry entry, Class c) {
|
||||||
return test(entry.newClass(c));
|
return test(entry.newClass(c), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run test with a given Entry
|
// Run test with a given Entry
|
||||||
static DEREncodable test(PEMData.Entry entry) {
|
static DEREncodable test(PEMData.Entry entry) {
|
||||||
|
return test(entry, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run test with a given Entry
|
||||||
|
static DEREncodable test(PEMData.Entry entry, boolean withFactory) {
|
||||||
|
System.out.printf("Testing %s %s%n", entry.name(), entry.provider());
|
||||||
try {
|
try {
|
||||||
DEREncodable r = test(entry.pem(), entry.clazz(), PEMDecoder.of());
|
PEMDecoder pemDecoder;
|
||||||
|
if (withFactory) {
|
||||||
|
Provider provider = Security.getProvider(entry.provider());
|
||||||
|
pemDecoder = PEMDecoder.of().withFactory(provider);
|
||||||
|
} else {
|
||||||
|
pemDecoder = PEMDecoder.of();
|
||||||
|
}
|
||||||
|
DEREncodable r = test(entry.pem(), entry.clazz(), pemDecoder);
|
||||||
System.out.println("PASS (" + entry.name() + ")");
|
System.out.println("PASS (" + entry.name() + ")");
|
||||||
return r;
|
return r;
|
||||||
} catch (Exception | AssertionError e) {
|
} catch (Exception | AssertionError e) {
|
||||||
@ -412,6 +456,19 @@ public class PEMDecoderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testPKCS8Key(PEMData.Entry entry) {
|
||||||
|
try {
|
||||||
|
PKCS8Key key = PEMDecoder.of().decode(entry.pem(), PKCS8Key.class);
|
||||||
|
PKCS8EncodedKeySpec spec =
|
||||||
|
new PKCS8EncodedKeySpec(key.getEncoded());
|
||||||
|
|
||||||
|
KeyFactory kf = KeyFactory.getInstance(key.getAlgorithm());
|
||||||
|
kf.generatePublic(spec);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void testClass(PEMData.Entry entry, Class clazz) throws IOException {
|
static void testClass(PEMData.Entry entry, Class clazz) throws IOException {
|
||||||
var pk = PEMDecoder.of().decode(entry.pem(), clazz);
|
var pk = PEMDecoder.of().decode(entry.pem(), clazz);
|
||||||
}
|
}
|
||||||
@ -472,9 +529,15 @@ public class PEMDecoderTest {
|
|||||||
"should not be null");
|
"should not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AlgorithmParameterSpec spec = null;
|
||||||
String algorithm = switch(privateKey.getAlgorithm()) {
|
String algorithm = switch(privateKey.getAlgorithm()) {
|
||||||
case "EC" -> "SHA256withECDSA";
|
case "EC" -> "SHA256withECDSA";
|
||||||
case "EdDSA" -> "EdDSA";
|
case "EdDSA" -> "EdDSA";
|
||||||
|
case "RSASSA-PSS" -> {
|
||||||
|
spec = new PSSParameterSpec(
|
||||||
|
"SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
|
||||||
|
yield "RSASSA-PSS";
|
||||||
|
}
|
||||||
case null -> {
|
case null -> {
|
||||||
System.out.println("Algorithm is null " +
|
System.out.println("Algorithm is null " +
|
||||||
entry.name());
|
entry.name());
|
||||||
@ -487,6 +550,9 @@ public class PEMDecoderTest {
|
|||||||
try {
|
try {
|
||||||
if (d instanceof PrivateKey) {
|
if (d instanceof PrivateKey) {
|
||||||
s = Signature.getInstance(algorithm);
|
s = Signature.getInstance(algorithm);
|
||||||
|
if (spec != null) {
|
||||||
|
s.setParameter(spec);
|
||||||
|
}
|
||||||
s.initSign(privateKey);
|
s.initSign(privateKey);
|
||||||
s.update(data);
|
s.update(data);
|
||||||
s.sign();
|
s.sign();
|
||||||
|
@ -26,9 +26,15 @@
|
|||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8298420
|
* @bug 8298420
|
||||||
|
* @library /test/lib
|
||||||
* @summary Testing basic PEM API encoding
|
* @summary Testing basic PEM API encoding
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @modules java.base/sun.security.util
|
* @modules java.base/sun.security.util
|
||||||
|
* @run main PEMEncoderTest PBEWithHmacSHA256AndAES_128
|
||||||
|
* @run main/othervm -Djava.security.properties=${test.src}/java.security-anotherAlgo
|
||||||
|
* PEMEncoderTest PBEWithHmacSHA512AndAES_256
|
||||||
|
* @run main/othervm -Djava.security.properties=${test.src}/java.security-emptyAlgo
|
||||||
|
* PEMEncoderTest PBEWithHmacSHA256AndAES_128
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import sun.security.util.Pem;
|
import sun.security.util.Pem;
|
||||||
@ -39,13 +45,22 @@ import javax.crypto.spec.PBEParameterSpec;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.spec.InvalidParameterSpecException;
|
import java.security.spec.InvalidParameterSpecException;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import jdk.test.lib.security.SecurityUtils;
|
||||||
|
|
||||||
|
import static jdk.test.lib.Asserts.assertEquals;
|
||||||
|
import static jdk.test.lib.Asserts.assertThrows;
|
||||||
|
|
||||||
public class PEMEncoderTest {
|
public class PEMEncoderTest {
|
||||||
|
|
||||||
static Map<String, DEREncodable> keymap;
|
static Map<String, DEREncodable> keymap;
|
||||||
|
static String pkcs8DefaultAlgExpect;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
pkcs8DefaultAlgExpect = args[0];
|
||||||
PEMEncoder encoder = PEMEncoder.of();
|
PEMEncoder encoder = PEMEncoder.of();
|
||||||
|
|
||||||
// These entries are removed
|
// These entries are removed
|
||||||
@ -63,7 +78,12 @@ public class PEMEncoderTest {
|
|||||||
System.out.println("New instance re-encode testToString:");
|
System.out.println("New instance re-encode testToString:");
|
||||||
keymap.keySet().stream().forEach(key -> testToString(key,
|
keymap.keySet().stream().forEach(key -> testToString(key,
|
||||||
PEMEncoder.of()));
|
PEMEncoder.of()));
|
||||||
|
System.out.println("Same instance Encoder testEncodedKeySpec:");
|
||||||
|
testEncodedKeySpec(encoder);
|
||||||
|
System.out.println("New instance Encoder testEncodedKeySpec:");
|
||||||
|
testEncodedKeySpec(PEMEncoder.of());
|
||||||
|
System.out.println("Same instance Encoder testEmptyKey:");
|
||||||
|
testEmptyAndNullKey(encoder);
|
||||||
keymap = generateObjKeyMap(PEMData.encryptedList);
|
keymap = generateObjKeyMap(PEMData.encryptedList);
|
||||||
System.out.println("Same instance Encoder match test:");
|
System.out.println("Same instance Encoder match test:");
|
||||||
keymap.keySet().stream().forEach(key -> testEncryptedMatch(key, encoder));
|
keymap.keySet().stream().forEach(key -> testEncryptedMatch(key, encoder));
|
||||||
@ -86,6 +106,13 @@ public class PEMEncoderTest {
|
|||||||
PEMRecord pemRecord =
|
PEMRecord pemRecord =
|
||||||
d.decode(PEMData.ed25519ep8.pem(), PEMRecord.class);
|
d.decode(PEMData.ed25519ep8.pem(), PEMRecord.class);
|
||||||
PEMData.checkResults(PEMData.ed25519ep8, pemRecord.toString());
|
PEMData.checkResults(PEMData.ed25519ep8, pemRecord.toString());
|
||||||
|
|
||||||
|
// test PemRecord is encapsulated with PEM header and footer on encoding
|
||||||
|
String[] pemLines = PEMData.ed25519ep8.pem().split("\n");
|
||||||
|
String[] pemNoHeaderFooter = Arrays.copyOfRange(pemLines, 1, pemLines.length - 1);
|
||||||
|
PEMRecord pemR = new PEMRecord("ENCRYPTED PRIVATE KEY", String.join("\n",
|
||||||
|
pemNoHeaderFooter));
|
||||||
|
PEMData.checkResults(PEMData.ed25519ep8.pem(), encoder.encodeToString(pemR));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map generateObjKeyMap(List<PEMData.Entry> list) {
|
static Map generateObjKeyMap(List<PEMData.Entry> list) {
|
||||||
@ -145,10 +172,12 @@ public class PEMEncoderTest {
|
|||||||
static void testEncrypted(String key, PEMEncoder encoder) {
|
static void testEncrypted(String key, PEMEncoder encoder) {
|
||||||
PEMData.Entry entry = PEMData.getEntry(key);
|
PEMData.Entry entry = PEMData.getEntry(key);
|
||||||
try {
|
try {
|
||||||
encoder.withEncryption(
|
String pem = encoder.withEncryption(
|
||||||
(entry.password() != null ? entry.password() :
|
(entry.password() != null ? entry.password() :
|
||||||
"fish".toCharArray()))
|
"fish".toCharArray()))
|
||||||
.encodeToString(keymap.get(key));
|
.encodeToString(keymap.get(key));
|
||||||
|
|
||||||
|
verifyEncriptionAlg(pem);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
throw new AssertionError("Encrypted encoder failed with " +
|
throw new AssertionError("Encrypted encoder failed with " +
|
||||||
entry.name(), e);
|
entry.name(), e);
|
||||||
@ -157,6 +186,11 @@ public class PEMEncoderTest {
|
|||||||
System.out.println("PASS: " + entry.name());
|
System.out.println("PASS: " + entry.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void verifyEncriptionAlg(String pem) {
|
||||||
|
var epki = PEMDecoder.of().decode(pem, EncryptedPrivateKeyInfo.class);
|
||||||
|
assertEquals(epki.getAlgName(), pkcs8DefaultAlgExpect);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test cannot verify PEM was the same as known PEM because we have no
|
Test cannot verify PEM was the same as known PEM because we have no
|
||||||
public access to the AlgoritmID.params and PBES2Parameters.
|
public access to the AlgoritmID.params and PBES2Parameters.
|
||||||
@ -195,5 +229,42 @@ public class PEMEncoderTest {
|
|||||||
PEMData.checkResults(entry, result);
|
PEMData.checkResults(entry, result);
|
||||||
System.out.println("PASS: " + entry.name());
|
System.out.println("PASS: " + entry.name());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
static void testEncodedKeySpec(PEMEncoder encoder) throws NoSuchAlgorithmException {
|
||||||
|
KeyPair kp = getKeyPair();
|
||||||
|
encoder.encodeToString(new X509EncodedKeySpec(kp.getPublic().getEncoded()));
|
||||||
|
encoder.encodeToString(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded()));
|
||||||
|
System.out.println("PASS: testEncodedKeySpec");
|
||||||
|
}
|
||||||
|
private static void testEmptyAndNullKey(PEMEncoder encoder) throws NoSuchAlgorithmException {
|
||||||
|
KeyPair kp = getKeyPair();
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
|
||||||
|
new KeyPair(kp.getPublic(), new EmptyKey())));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
|
||||||
|
new KeyPair(kp.getPublic(), null)));
|
||||||
|
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
|
||||||
|
new KeyPair(new EmptyKey(), kp.getPrivate())));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> encoder.encode(
|
||||||
|
new KeyPair(null, kp.getPrivate())));
|
||||||
|
System.out.println("PASS: testEmptyKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
|
||||||
|
Provider provider = Security.getProvider("SunRsaSign");
|
||||||
|
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider);
|
||||||
|
kpg.initialize(SecurityUtils.getTestKeySize("RSA"));
|
||||||
|
return kpg.generateKeyPair();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class EmptyKey implements PublicKey, PrivateKey {
|
||||||
|
@Override
|
||||||
|
public String getAlgorithm() { return "Test"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFormat() { return "Test"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getEncoded() { return new byte[0]; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
97
test/jdk/java/security/PEM/PEMMultiThreadTest.java
Normal file
97
test/jdk/java/security/PEM/PEMMultiThreadTest.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8298420
|
||||||
|
* @library /test/lib
|
||||||
|
* @summary Testing PEM API is thread safe
|
||||||
|
* @enablePreview
|
||||||
|
* @modules java.base/sun.security.util
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.security.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import jdk.test.lib.security.SecurityUtils;
|
||||||
|
|
||||||
|
public class PEMMultiThreadTest {
|
||||||
|
static final int THREAD_COUNT = 5;
|
||||||
|
static final int KEYS_COUNT = 50;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
PEMEncoder encoder = PEMEncoder.of();
|
||||||
|
try (ExecutorService ex = Executors.newFixedThreadPool(THREAD_COUNT)) {
|
||||||
|
Map<Integer, PublicKey> keys = new HashMap<>();
|
||||||
|
Map<Integer, String> encoded = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
Map<Integer, String> decoded = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
final CountDownLatch encodingComplete = new CountDownLatch(KEYS_COUNT);
|
||||||
|
final CountDownLatch decodingComplete = new CountDownLatch(KEYS_COUNT);
|
||||||
|
|
||||||
|
// Generate keys and encode them in parallel
|
||||||
|
for (int i = 0; i < KEYS_COUNT; i++) {
|
||||||
|
final int finalI = i;
|
||||||
|
KeyPair kp = getKeyPair();
|
||||||
|
keys.put(finalI, kp.getPublic());
|
||||||
|
|
||||||
|
ex.submit(() -> {
|
||||||
|
encoded.put(finalI, encoder.encodeToString(kp.getPublic()));
|
||||||
|
encodingComplete.countDown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
encodingComplete.await();
|
||||||
|
|
||||||
|
// Decode keys in parallel
|
||||||
|
PEMDecoder decoder = PEMDecoder.of();
|
||||||
|
for (Map.Entry<Integer, String> entry : encoded.entrySet()) {
|
||||||
|
ex.submit(() -> {
|
||||||
|
decoded.put(entry.getKey(), decoder.decode(entry.getValue(), PublicKey.class)
|
||||||
|
.toString());
|
||||||
|
decodingComplete.countDown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
decodingComplete.await();
|
||||||
|
|
||||||
|
// verify all keys were properly encoded and decoded comparing with the original key map
|
||||||
|
for (Map.Entry<Integer, PublicKey> kp : keys.entrySet()) {
|
||||||
|
if (!decoded.get(kp.getKey()).equals(kp.getValue().toString())) {
|
||||||
|
throw new RuntimeException("a key was not properly encoded and decoded: " + decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("PASS: testThreadSafety");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
|
||||||
|
String alg = "EC";
|
||||||
|
KeyPairGenerator kpg = KeyPairGenerator.getInstance(alg);
|
||||||
|
kpg.initialize(SecurityUtils.getTestKeySize(alg));
|
||||||
|
return kpg.generateKeyPair();
|
||||||
|
}
|
||||||
|
}
|
1
test/jdk/java/security/PEM/java.security-anotherAlgo
Normal file
1
test/jdk/java/security/PEM/java.security-anotherAlgo
Normal file
@ -0,0 +1 @@
|
|||||||
|
jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA512AndAES_256
|
1
test/jdk/java/security/PEM/java.security-emptyAlgo
Normal file
1
test/jdk/java/security/PEM/java.security-emptyAlgo
Normal file
@ -0,0 +1 @@
|
|||||||
|
jdk.epkcs8.defaultAlgorithm=
|
@ -25,11 +25,15 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules java.base/sun.security.util
|
||||||
* @bug 8298420
|
* @bug 8298420
|
||||||
* @summary Testing encryptKey
|
* @summary Testing encryptKey
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import sun.security.util.Pem;
|
||||||
|
|
||||||
import javax.crypto.EncryptedPrivateKeyInfo;
|
import javax.crypto.EncryptedPrivateKeyInfo;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.PBEParameterSpec;
|
import javax.crypto.spec.PBEParameterSpec;
|
||||||
@ -37,8 +41,13 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import java.security.AlgorithmParameters;
|
import java.security.AlgorithmParameters;
|
||||||
import java.security.PEMDecoder;
|
import java.security.PEMDecoder;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.Security;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static jdk.test.lib.Asserts.assertEquals;
|
||||||
|
|
||||||
public class EncryptKey {
|
public class EncryptKey {
|
||||||
|
|
||||||
private static final String encEdECKey =
|
private static final String encEdECKey =
|
||||||
@ -56,6 +65,8 @@ public class EncryptKey {
|
|||||||
passwdText.getBytes(), "PBE");
|
passwdText.getBytes(), "PBE");
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE"));
|
||||||
|
|
||||||
EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey,
|
EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey,
|
||||||
EncryptedPrivateKeyInfo.class);
|
EncryptedPrivateKeyInfo.class);
|
||||||
PrivateKey priKey = PEMDecoder.of().withDecryption(password).
|
PrivateKey priKey = PEMDecoder.of().withDecryption(password).
|
||||||
@ -71,6 +82,19 @@ public class EncryptKey {
|
|||||||
" with expected.");
|
" with expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test encryptKey(PrivateKey, char[], String, ...) with provider
|
||||||
|
e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, ekpi.getAlgName(),
|
||||||
|
ap.getParameterSpec(PBEParameterSpec.class), p);
|
||||||
|
if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) {
|
||||||
|
throw new AssertionError("encryptKey() didn't match" +
|
||||||
|
" with expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test encryptKey(PrivateKey, char[], String, ...) with provider and null algorithm
|
||||||
|
e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, null, null,
|
||||||
|
p);
|
||||||
|
assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO);
|
||||||
|
|
||||||
// Test encryptKey(PrivateKey, Key, String, ...)
|
// Test encryptKey(PrivateKey, Key, String, ...)
|
||||||
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
|
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
|
||||||
ap.getParameterSpec(PBEParameterSpec.class),null, null);
|
ap.getParameterSpec(PBEParameterSpec.class),null, null);
|
||||||
@ -78,5 +102,26 @@ public class EncryptKey {
|
|||||||
throw new AssertionError("encryptKey() didn't match" +
|
throw new AssertionError("encryptKey() didn't match" +
|
||||||
" with expected.");
|
" with expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test encryptKey(PrivateKey, Key, String, ...) with provider and null random
|
||||||
|
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
|
||||||
|
ap.getParameterSpec(PBEParameterSpec.class), p, null);
|
||||||
|
if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) {
|
||||||
|
throw new AssertionError("encryptKey() didn't match" +
|
||||||
|
" with expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test encryptKey(PrivateKey, Key, String, ...) with provider and SecureRandom
|
||||||
|
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(),
|
||||||
|
ap.getParameterSpec(PBEParameterSpec.class), p, new SecureRandom());
|
||||||
|
if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) {
|
||||||
|
throw new AssertionError("encryptKey() didn't match" +
|
||||||
|
" with expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test encryptKey(PrivateKey, Key, String, ...) with provider and null algorithm
|
||||||
|
e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, null, null,
|
||||||
|
p, new SecureRandom());
|
||||||
|
assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ import javax.crypto.SecretKey;
|
|||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.security.PEMDecoder;
|
import java.security.PEMDecoder;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.Security;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class GetKey {
|
public class GetKey {
|
||||||
@ -48,12 +50,29 @@ public class GetKey {
|
|||||||
IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo=
|
IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo=
|
||||||
-----END ENCRYPTED PRIVATE KEY-----
|
-----END ENCRYPTED PRIVATE KEY-----
|
||||||
""";
|
""";
|
||||||
|
private static final String encDHECKey =
|
||||||
|
"""
|
||||||
|
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||||
|
MIIBvDBmBgkqhkiG9w0BBQ0wWTA4BgkqhkiG9w0BBQwwKwQUN8pkErJx7aqH0fJF
|
||||||
|
BcOadPKiuRoCAhAAAgEQMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBAT1Vwd
|
||||||
|
gU4rTd6zy7lKr4wmBIIBUMe+2+O0AG6t4CMSHcDVceRg2jvbs5PmPjW4Ka5mDich
|
||||||
|
hVEsjSpJLbUyJdbji6UaiUpuWgvYSMLZ10pfhOFw/ssXwCw+JrlXUqDpQGLaW8ZR
|
||||||
|
zSL3CoozTI2Y6EBdWt53KbySwtZMoTpW/W3vPi98bJXtR635msf6gYXmSUP7DyoJ
|
||||||
|
79dxz3pRYsnOuBe0yZ2wTq9iMgTMudzLJAFX2qyi+3KOb1g5Va9DYAqJmzCYOd74
|
||||||
|
+I+0gGNFtSc1vGQYr3cAfcKT8AZ1RHE4IkpnpgFD5HsZ8f4hy0yK8juk9NE9Gzuy
|
||||||
|
B929LBXk6V3L0MKzIABS3QvAlhWETM6XtGBDugzAgsooo9lEHLwYRldvOlL+QYyE
|
||||||
|
CtqDmXOrgEMWvxWGEFCTKYhKkqMKjU3y3GiozEEdb9j2okW1s30yHQjIoj0OR4nB
|
||||||
|
D8GeP0QnY73NfbOw7z81TA==
|
||||||
|
-----END ENCRYPTED PRIVATE KEY-----
|
||||||
|
""";
|
||||||
private static final String passwdText = "fish";
|
private static final String passwdText = "fish";
|
||||||
private static final char[] password = passwdText.toCharArray();
|
private static final char[] password = passwdText.toCharArray();
|
||||||
private static final SecretKey key = new SecretKeySpec(
|
private static final SecretKey key = new SecretKeySpec(
|
||||||
passwdText.getBytes(), "PBE");
|
passwdText.getBytes(), "PBE");
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE"));
|
||||||
|
|
||||||
EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey,
|
EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey,
|
||||||
EncryptedPrivateKeyInfo.class);
|
EncryptedPrivateKeyInfo.class);
|
||||||
PrivateKey priKey = PEMDecoder.of().withDecryption(password).
|
PrivateKey priKey = PEMDecoder.of().withDecryption(password).
|
||||||
@ -66,11 +85,23 @@ public class GetKey {
|
|||||||
+ "match with expected.");
|
+ "match with expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test getKey(key, provider)
|
// Test getKey(key, provider) provider null
|
||||||
if (!Arrays.equals(priKey.getEncoded(),
|
if (!Arrays.equals(priKey.getEncoded(),
|
||||||
ekpi.getKey(key, null).getEncoded())) {
|
ekpi.getKey(key, null).getEncoded())) {
|
||||||
throw new AssertionError("getKey(key, provider) " +
|
throw new AssertionError("getKey(key, provider) " +
|
||||||
"didn't match with expected.");
|
"didn't match with expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test getKey(key, provider) with provider
|
||||||
|
EncryptedPrivateKeyInfo ekpiDH = PEMDecoder.of().decode(encDHECKey,
|
||||||
|
EncryptedPrivateKeyInfo.class);
|
||||||
|
PrivateKey priKeyDH = PEMDecoder.of().withDecryption(password).
|
||||||
|
decode(encDHECKey, PrivateKey.class);
|
||||||
|
|
||||||
|
if (!Arrays.equals(priKeyDH.getEncoded(),
|
||||||
|
ekpiDH.getKey(key, p).getEncoded())) {
|
||||||
|
throw new AssertionError("getKey(key, provider) " +
|
||||||
|
"didn't match with expected.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,13 @@
|
|||||||
* java.base/sun.security.provider
|
* java.base/sun.security.provider
|
||||||
* java.base/sun.security.x509
|
* java.base/sun.security.x509
|
||||||
* @run main PKCS8Test
|
* @run main PKCS8Test
|
||||||
|
* @run main/othervm -Dtest.provider.name=SunJCE PKCS8Test
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.Security;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HexFormat;
|
import java.util.HexFormat;
|
||||||
|
|
||||||
@ -45,6 +48,7 @@ import sun.security.provider.DSAPrivateKey;
|
|||||||
|
|
||||||
public class PKCS8Test {
|
public class PKCS8Test {
|
||||||
|
|
||||||
|
static Provider provider;
|
||||||
static final String FORMAT = "PKCS#8";
|
static final String FORMAT = "PKCS#8";
|
||||||
static final String EXPECTED_ALG_ID_CHRS = "DSA, \n" +
|
static final String EXPECTED_ALG_ID_CHRS = "DSA, \n" +
|
||||||
"\tp: 02\n\tq: 03\n\tg: 04\n";
|
"\tp: 02\n\tq: 03\n\tg: 04\n";
|
||||||
@ -59,7 +63,7 @@ public class PKCS8Test {
|
|||||||
"0403020101"); // PrivateKey OCTET int x = 1
|
"0403020101"); // PrivateKey OCTET int x = 1
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
provider = Security.getProvider(System.getProperty("test.provider.name"));
|
||||||
byte[] encodedKey = new DSAPrivateKey(
|
byte[] encodedKey = new DSAPrivateKey(
|
||||||
BigInteger.valueOf(1),
|
BigInteger.valueOf(1),
|
||||||
BigInteger.valueOf(2),
|
BigInteger.valueOf(2),
|
||||||
@ -73,7 +77,8 @@ public class PKCS8Test {
|
|||||||
.toString(encodedKey));
|
.toString(encodedKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
PKCS8Key decodedKey = (PKCS8Key)PKCS8Key.parseKey(encodedKey);
|
PKCS8Key decodedKey = provider == null ? (PKCS8Key)PKCS8Key.parseKey(encodedKey) :
|
||||||
|
(PKCS8Key)PKCS8Key.parseKey(encodedKey, provider);
|
||||||
|
|
||||||
assert(ALGORITHM.equalsIgnoreCase(decodedKey.getAlgorithm()));
|
assert(ALGORITHM.equalsIgnoreCase(decodedKey.getAlgorithm()));
|
||||||
assert(FORMAT.equalsIgnoreCase(decodedKey.getFormat()));
|
assert(FORMAT.equalsIgnoreCase(decodedKey.getFormat()));
|
||||||
@ -126,7 +131,11 @@ public class PKCS8Test {
|
|||||||
original[1] = (byte) (length - 2); // the length field inside DER
|
original[1] = (byte) (length - 2); // the length field inside DER
|
||||||
original[4] = (byte) newVersion; // the version inside DER
|
original[4] = (byte) newVersion; // the version inside DER
|
||||||
try {
|
try {
|
||||||
|
if (provider == null) {
|
||||||
PKCS8Key.parseKey(original);
|
PKCS8Key.parseKey(original);
|
||||||
|
} else {
|
||||||
|
PKCS8Key.parseKey(original, provider);
|
||||||
|
}
|
||||||
} catch (InvalidKeyException e) {
|
} catch (InvalidKeyException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -45,6 +45,8 @@ public final class SecurityUtils {
|
|||||||
private enum KeySize{
|
private enum KeySize{
|
||||||
RSA(2048),
|
RSA(2048),
|
||||||
DSA(2048),
|
DSA(2048),
|
||||||
|
Ed25519(256),
|
||||||
|
EC(256),
|
||||||
DH(2048);
|
DH(2048);
|
||||||
|
|
||||||
private final int keySize;
|
private final int keySize;
|
||||||
@ -145,6 +147,8 @@ public final class SecurityUtils {
|
|||||||
return switch (algo) {
|
return switch (algo) {
|
||||||
case "RSA" -> KeySize.RSA.keySize;
|
case "RSA" -> KeySize.RSA.keySize;
|
||||||
case "DSA" -> KeySize.DSA.keySize;
|
case "DSA" -> KeySize.DSA.keySize;
|
||||||
|
case "Ed25519" -> KeySize.Ed25519.keySize;
|
||||||
|
case "EC" -> KeySize.EC.keySize;
|
||||||
case "DH", "DiffieHellman" -> KeySize.DH.keySize;
|
case "DH", "DiffieHellman" -> KeySize.DH.keySize;
|
||||||
default -> throw new RuntimeException("Test key size not defined for " + algo);
|
default -> throw new RuntimeException("Test key size not defined for " + algo);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user