17
17
package org .springframework .boot .ssl .pem ;
18
18
19
19
import java .security .KeyStore ;
20
+ import java .util .Collections ;
21
+ import java .util .Set ;
20
22
23
+ import org .springframework .boot .io .ApplicationResourceLoader ;
21
24
import org .springframework .util .StringUtils ;
22
25
23
26
/**
29
32
* @param password the password used
30
33
* {@link KeyStore#setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[])
31
34
* setting key entries} in the {@link KeyStore}
32
- * @param certificates the certificates content (either the PEM content itself or or a
35
+ * @param certificateSet the set of certificates contents (either the PEM content itself or a
33
36
* reference to the resource to load). When a {@link #privateKey() private key} is present
34
37
* this value is treated as a certificate chain, otherwise it is treated a list of
35
38
* certificates that should all be registered.
36
39
* @param privateKey the private key content (either the PEM content itself or a reference
37
40
* to the resource to load)
38
41
* @param privateKeyPassword a password used to decrypt an encrypted private key
39
- * @param optional certificates/privateKey may be optional
40
42
* @author Scott Frederick
41
43
* @author Phillip Webb
42
44
* @since 3.1.0
43
45
* @see PemSslStore#load(PemSslStoreDetails)
44
46
*/
45
- public record PemSslStoreDetails (String type , String alias , String password , String certificates , String privateKey , String privateKeyPassword , boolean optional ) {
47
+ public record PemSslStoreDetails (String type , String alias , String password , Set <PemCertificate > certificateSet , String privateKey ,
48
+ String privateKeyPassword ) {
46
49
47
50
/**
48
51
* Create a new {@link PemSslStoreDetails} instance.
@@ -52,7 +55,7 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
52
55
* @param password the password used
53
56
* {@link KeyStore#setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[])
54
57
* setting key entries} in the {@link KeyStore}
55
- * @param certificates the certificate content (either the PEM content itself or a
58
+ * @param certificateSet the set of certificate content (either the PEM content itself or a
56
59
* reference to the resource to load)
57
60
* @param privateKey the private key content (either the PEM content itself or a
58
61
* reference to the resource to load)
@@ -62,6 +65,23 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
62
65
public PemSslStoreDetails {
63
66
}
64
67
68
+ /**
69
+ * Create a new {@link PemSslStoreDetails} instance.
70
+ * @param type the key store type, for example {@code JKS} or {@code PKCS11}. A
71
+ * {@code null} value will use {@link KeyStore#getDefaultType()}).
72
+ * @param alias the alias used when setting entries in the {@link KeyStore}
73
+ * @param password the password used
74
+ * @param certificates the certificate content (either the PEM content itself or a
75
+ * reference to the resource to load)
76
+ * @param privateKey the private key content (either the PEM content itself or a
77
+ * reference to the resource to load)
78
+ * @param privateKeyPassword a password used to decrypt an encrypted private key
79
+ */
80
+ @ Deprecated
81
+ public PemSslStoreDetails (String type , String alias , String password , String certificates , String privateKey , String privateKeyPassword ) {
82
+ this (type , alias , password , toPemCertificates (certificates ), privateKey , privateKeyPassword );
83
+ }
84
+
65
85
/**
66
86
* Create a new {@link PemSslStoreDetails} instance.
67
87
* @param type the key store type, for example {@code JKS} or {@code PKCS11}. A
@@ -71,10 +91,10 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
71
91
* @param privateKey the private key content (either the PEM content itself or a
72
92
* reference to the resource to load)
73
93
* @param privateKeyPassword a password used to decrypt an encrypted private key
74
- * @param optional certificates/privateKey may be optional
75
94
*/
76
- public PemSslStoreDetails (String type , String certificate , String privateKey , String privateKeyPassword , boolean optional ) {
77
- this (type , null , null , certificate , privateKey , privateKeyPassword , optional );
95
+ @ Deprecated
96
+ public PemSslStoreDetails (String type , String certificate , String privateKey , String privateKeyPassword ) {
97
+ this (type , null , null , certificate , privateKey , privateKeyPassword );
78
98
}
79
99
80
100
/**
@@ -86,8 +106,48 @@ public PemSslStoreDetails(String type, String certificate, String privateKey, St
86
106
* @param privateKey the private key content (either the PEM content itself or a
87
107
* reference to the resource to load)
88
108
*/
109
+ @ Deprecated
89
110
public PemSslStoreDetails (String type , String certificate , String privateKey ) {
90
- this (type , certificate , privateKey , null , false );
111
+ this (type , certificate , privateKey , null );
112
+ }
113
+
114
+ /**
115
+ * Create a new {@link PemSslStoreDetails} instance.
116
+ * @param type the key store type, for example {@code JKS} or {@code PKCS11}. A
117
+ * {@code null} value will use {@link KeyStore#getDefaultType()}).
118
+ * @param certificates the set of certificate contents (either the PEM content itself or a
119
+ * reference to the resource to load)
120
+ * @param privateKey the private key content (either the PEM content itself or a
121
+ * reference to the resource to load)
122
+ * @param privateKeyPassword a password used to decrypt an encrypted private key
123
+ */
124
+ public PemSslStoreDetails (String type , Set <PemCertificate > certificates , String privateKey , String privateKeyPassword ) {
125
+ this (type , null , null , certificates , privateKey , privateKeyPassword );
126
+ }
127
+
128
+ /**
129
+ * Create a new {@link PemSslStoreDetails} instance.
130
+ * @param type the key store type, for example {@code JKS} or {@code PKCS11}. A
131
+ * {@code null} value will use {@link KeyStore#getDefaultType()}).
132
+ * @param certificates the set of certificate contents (either the PEM content itself or a
133
+ * reference to the resource to load)
134
+ * @param privateKey the private key content (either the PEM content itself or a
135
+ * reference to the resource to load)
136
+ */
137
+ public PemSslStoreDetails (String type , Set <PemCertificate > certificates , String privateKey ) {
138
+ this (type , certificates , privateKey , null );
139
+ }
140
+
141
+ /**
142
+ * Return the certificate content.
143
+ * @return the certificate content
144
+ * @deprecated
145
+ */
146
+ @ Deprecated ()
147
+ public String certificates () {
148
+ return this .certificateSet .stream ()
149
+ .findAny ().map (PemCertificate ::location )
150
+ .orElse (null );
91
151
}
92
152
93
153
/**
@@ -97,7 +157,8 @@ public PemSslStoreDetails(String type, String certificate, String privateKey) {
97
157
* @since 3.2.0
98
158
*/
99
159
public PemSslStoreDetails withAlias (String alias ) {
100
- return new PemSslStoreDetails (this .type , alias , this .password , this .certificates , this .privateKey , this .privateKeyPassword , this .optional );
160
+ return new PemSslStoreDetails (this .type , alias , this .password , this .certificateSet , this .privateKey ,
161
+ this .privateKeyPassword );
101
162
}
102
163
103
164
/**
@@ -107,7 +168,8 @@ public PemSslStoreDetails withAlias(String alias) {
107
168
* @since 3.2.0
108
169
*/
109
170
public PemSslStoreDetails withPassword (String password ) {
110
- return new PemSslStoreDetails (this .type , this .alias , password , this .certificates , this .privateKey , this .privateKeyPassword , this .optional );
171
+ return new PemSslStoreDetails (this .type , this .alias , password , this .certificateSet , this .privateKey ,
172
+ this .privateKeyPassword );
111
173
}
112
174
113
175
/**
@@ -116,7 +178,8 @@ public PemSslStoreDetails withPassword(String password) {
116
178
* @return a new {@link PemSslStoreDetails} instance
117
179
*/
118
180
public PemSslStoreDetails withPrivateKey (String privateKey ) {
119
- return new PemSslStoreDetails (this .type , this .alias , this .password , this .certificates , privateKey , this .privateKeyPassword , this .optional );
181
+ return new PemSslStoreDetails (this .type , this .alias , this .password , this .certificateSet , privateKey ,
182
+ this .privateKeyPassword );
120
183
}
121
184
122
185
/**
@@ -125,17 +188,25 @@ public PemSslStoreDetails withPrivateKey(String privateKey) {
125
188
* @return a new {@link PemSslStoreDetails} instance
126
189
*/
127
190
public PemSslStoreDetails withPrivateKeyPassword (String privateKeyPassword ) {
128
- return new PemSslStoreDetails (this .type , this .alias , this .password , this .certificates , this .privateKey , privateKeyPassword , this . optional );
191
+ return new PemSslStoreDetails (this .type , this .alias , this .password , this .certificateSet , this .privateKey , privateKeyPassword );
129
192
}
130
193
131
194
boolean isEmpty () {
132
- return isEmpty (this .type ) && isEmpty ( this . certificates ) && isEmpty (this .privateKey );
195
+ return isEmpty (this .type ) && isCertificatesEmpty ( ) && isEmpty (this .privateKey );
133
196
}
134
197
135
198
private boolean isEmpty (String value ) {
136
199
return !StringUtils .hasText (value );
137
200
}
138
201
202
+ private boolean isContentEmpty (PemCertificate value ) {
203
+ return value .optional () ? !new ApplicationResourceLoader ().getResource (value .location ()).exists () : isEmpty (value .location ());
204
+ }
205
+
206
+ boolean isCertificatesEmpty () {
207
+ return this .certificateSet == null || this .certificateSet .isEmpty () || this .certificateSet .stream ().allMatch (this ::isContentEmpty );
208
+ }
209
+
139
210
/**
140
211
* Factory method to create a new {@link PemSslStoreDetails} instance for the given
141
212
* certificate. <b>Note:</b> This method doesn't actually check if the provided value
@@ -161,4 +232,11 @@ public static PemSslStoreDetails forCertificates(String certificates) {
161
232
return new PemSslStoreDetails (null , certificates , null );
162
233
}
163
234
164
- }
235
+ private static Set <PemCertificate > toPemCertificates (String certificates ) {
236
+ if (certificates != null ) {
237
+ return Set .of (new PemCertificate (certificates ));
238
+ }
239
+ return Collections .emptySet ();
240
+ }
241
+
242
+ }
0 commit comments