3131 */
3232public class VaultCertificateRequest {
3333
34+ private static String DEFAULT_FORMAT = "der" ;
35+
3436 /**
3537 * The CN of the certificate. Should match the host name.
3638 */
@@ -51,24 +53,39 @@ public class VaultCertificateRequest {
5153 */
5254 private final List <String > uriSubjectAltNames ;
5355
56+ /**
57+ * Specifies custom OID/UTF8-string Subject Alternative Names. These must match values
58+ * specified on the role in {@literal allowed_other_sans}. The format is the same as
59+ * OpenSSL: {@literal <oid>;<type>:<value>} where the only current valid type is UTF8.
60+ * @since 2.4
61+ */
62+ private final List <String > otherSans ;
63+
5464 /**
5565 * Requested Time to Live
5666 */
5767 @ Nullable
5868 private final Duration ttl ;
5969
6070 /**
61- * Specifies the format for returned data. Can be pem, der, or pem_bundle; defaults to
62- * pem
71+ * Specifies the format for returned data. Can be {@literal pem}, {@literal der}, or
72+ * {@literal pem_bundle}; defaults to {@literal der} (in vault api the default is
73+ * {@literal pem}). If der, the output is base64 encoded. If {@literal pem_bundle},
74+ * the certificate field will contain the private key and certificate, concatenated;
75+ * if the issuing CA is not a Vault-derived self-signed root, this will be included as
76+ * well.
77+ * @since 2.4
6378 */
6479 private final String format ;
6580
6681 /**
67- * Specifies the format for marshaling the private key. Defaults to der which will
68- * return either base64-encoded DER or PEM-encoded DER, depending on the value of
69- * format. The other option is pkcs8 which will return the key marshalled as
70- * PEM-encoded PKCS8.
82+ * Specifies the format for marshaling the private key. Defaults to {@literal der}
83+ * which will return either base64-encoded DER or PEM-encoded DER, depending on the
84+ * value of {@literal format}. The other option is {@literal pkcs8} which will return
85+ * the key marshalled as PEM-encoded PKCS8.
86+ * @since 2.4
7187 */
88+ @ Nullable
7289 private final String privateKeyFormat ;
7390
7491 /**
@@ -79,17 +96,19 @@ public class VaultCertificateRequest {
7996 private final boolean excludeCommonNameFromSubjectAltNames ;
8097
8198 private VaultCertificateRequest (String commonName , List <String > altNames , List <String > ipSubjectAltNames ,
82- List <String > uriSubjectAltNames , @ Nullable Duration ttl , String format , String privateKeyFormat ,
99+ List <String > uriSubjectAltNames , List <String > otherSans , @ Nullable Duration ttl ,
100+ String format , @ Nullable String privateKeyFormat ,
83101 boolean excludeCommonNameFromSubjectAltNames ) {
84102
85103 this .commonName = commonName ;
86104 this .altNames = altNames ;
87105 this .ipSubjectAltNames = ipSubjectAltNames ;
88106 this .uriSubjectAltNames = uriSubjectAltNames ;
107+ this .otherSans = otherSans ;
89108 this .ttl = ttl ;
109+ this .excludeCommonNameFromSubjectAltNames = excludeCommonNameFromSubjectAltNames ;
90110 this .format = format ;
91111 this .privateKeyFormat = privateKeyFormat ;
92- this .excludeCommonNameFromSubjectAltNames = excludeCommonNameFromSubjectAltNames ;
93112 }
94113
95114 /**
@@ -124,6 +143,10 @@ public List<String> getUriSubjectAltNames() {
124143 return this .uriSubjectAltNames ;
125144 }
126145
146+ public List <String > getOtherSans () {
147+ return this .otherSans ;
148+ }
149+
127150 @ Nullable
128151 public Duration getTtl () {
129152 return this .ttl ;
@@ -133,6 +156,7 @@ public String getFormat() {
133156 return format ;
134157 }
135158
159+ @ Nullable
136160 public String getPrivateKeyFormat () {
137161 return privateKeyFormat ;
138162 }
@@ -152,11 +176,14 @@ public static class VaultCertificateRequestBuilder {
152176
153177 private List <String > uriSubjectAltNames = new ArrayList <>();
154178
179+ private List <String > otherSans = new ArrayList <>();
180+
155181 @ Nullable
156182 private Duration ttl ;
157183
158- private String format ;
184+ private String format = DEFAULT_FORMAT ;
159185
186+ @ Nullable
160187 private String privateKeyFormat ;
161188
162189 private boolean excludeCommonNameFromSubjectAltNames ;
@@ -259,6 +286,35 @@ public VaultCertificateRequestBuilder withUriSubjectAltName(String uriSubjectAlt
259286 return this ;
260287 }
261288
289+ /**
290+ * Configure custom OID/UTF8-string subject alternative names. Replaces previously
291+ * configured other subject alt names.
292+ * @param otherSans must not be {@literal null}.
293+ * @return {@code this} {@link VaultCertificateRequestBuilder}.
294+ * @since 2.4
295+ */
296+ public VaultCertificateRequestBuilder otherSans (Iterable <String > otherSans ) {
297+
298+ Assert .notNull (otherSans , "Other subject alt names must not be null" );
299+
300+ this .otherSans = toList (uriSubjectAltNames );
301+ return this ;
302+ }
303+
304+ /**
305+ * Add custom OID/UTF8-string subject alternative name.
306+ * @param otherSans must not be empty or {@literal null}.
307+ * @return {@code this} {@link VaultCertificateRequestBuilder}.
308+ * @since 2.4
309+ */
310+ public VaultCertificateRequestBuilder withOtherSans (String otherSans ) {
311+
312+ Assert .hasText (otherSans , "Other subject alt name must not be empty" );
313+
314+ this .otherSans .add (otherSans );
315+ return this ;
316+ }
317+
262318 /**
263319 * Configure a TTL.
264320 * @param ttl the time to live, in seconds, must not be negative.
@@ -392,8 +448,20 @@ public VaultCertificateRequest build() {
392448 uriSubjectAltNames = java .util .Collections .unmodifiableList (new ArrayList <>(this .uriSubjectAltNames ));
393449 }
394450
451+ List <String > otherSans ;
452+ switch (this .otherSans .size ()) {
453+ case 0 :
454+ otherSans = java .util .Collections .emptyList ();
455+ break ;
456+ case 1 :
457+ otherSans = java .util .Collections .singletonList (this .otherSans .get (0 ));
458+ break ;
459+ default :
460+ otherSans = java .util .Collections .unmodifiableList (new ArrayList <>(this .otherSans ));
461+ }
462+
395463 return new VaultCertificateRequest (this .commonName , altNames , ipSubjectAltNames , uriSubjectAltNames ,
396- this .ttl , this .format , this .privateKeyFormat , this .excludeCommonNameFromSubjectAltNames );
464+ otherSans , this .ttl , this .format , this .privateKeyFormat , this .excludeCommonNameFromSubjectAltNames );
397465 }
398466
399467 private static <E > List <E > toList (Iterable <E > iter ) {
0 commit comments