Hello.
I am currently using Spring Boot 3.3.1, I noticed the utility org.springframework.boot.ssl.pem.PemContent is very useful.
how about add a PropertyEditor to the package? here is my code:
package org.springframework.boot.ssl.pem;
import org.springframework.boot.ssl.pem.PemContent;
import org.springframework.util.StringUtils;
import java.beans.PropertyEditorSupport;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* @author Ying Zhuo
*/
public class PemContentEditor extends PropertyEditorSupport {
/**
* {@inheritDoc}
*/
@Override
public final void setAsText(String text) throws IllegalArgumentException {
try {
super.setValue(PemContent.of(trimContent(text)));
} catch (Exception e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
}
private String trimContent(String text) {
return Arrays.stream(StringUtils.delimitedListToStringArray(text, "\n"))
.map(String::trim)
.collect(Collectors.joining("\n"));
}
}
so i can config my bean like this:
<bean id="jwtSigner" class="com.mycompany.myproject.jwt.signer.AsymmetricSignerFactoryBean">
<property name="certificateContent">
<value>
<![CDATA[
-----BEGIN CERTIFICATE-----
x509 format content here
-----END CERTIFICATE-----
]]>
</value>
</property>
<property name="keyContent">
<value>
<![CDATA[
-----BEGIN PRIVATE KEY-----
PKCS#8 format content here
-----END PRIVATE KEY-----
]]>
</value>
</property>
<property name="keyPassword">
<null/>
</property>
</bean>
@scottfrederick your code of SSL is very cool, thanks.
Comment From: philwebb
I'm not to keen to add a PropertyEditor, but a Converter might be an option. I wonder if ObjectToObjectConverter might work out-of-the-box if we refined the of method to deal with trimming strings.
Comment From: philwebb
We discussed this today and we don't think we should add the property editor, but we do think we can make the of() method do the trimming.
Comment From: yingzhuo
We discussed this today and we don't think we should add the property editor, but we do think we can make the
of()method do the trimming.
Thank you, sir. I am so glad to hear that.
Comment From: wilkinsona
If we refine only of, I wonder if isPresentInText(String) and the various load methods behaving differently will cause confusion. It feels like trimming should either be done consistently or it should only be done by a method that makes it clear that its behavior is different. Perhaps of could be that method but it feels a bit hidden and might be better if the method name made the behavior clear.
Comment From: yingzhuo
Perhaps
ofcould be that method but it feels a bit hidden and might be better if the method name made the behavior clear.
just a hint, sir.
ObjectToObjectConverter can only find static method valueOf() or of(). if method name be 'ofTrimmedString()'
the converter cannot work.
Comment From: mhalbritter
Is the trimming necessary? the getCertificates and getPrivateKey methods also work with un-trimmed content (they ignore everything before the --- BEGIN header and the footer and don't care about whitespace in between).
The only way to get the original un-trimmed content back is by calling toString.
So maybe just adding a converter without the trimming is sufficient?
@yingzhuo did i miss something? Is the trimming necessary?
Comment From: yingzhuo
@mhalbritter Thank you. sir my suggestion is: trim each line of content, including footer and header.
/*
TEST NG
java.lang.IllegalStateException: Missing certificates or unrecognized format
at org.springframework.util.Assert.state(Assert.java:76)
at org.springframework.boot.ssl.pem.PemCertificateParser.parse(PemCertificateParser.java:64)
at org.springframework.boot.ssl.pem.PemContent.getCertificates(PemContent.java:64)
at com.github.yingzhuo.playground.PemContentTestCase.test1(PemContentTestCase.java:22)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
*/
@Test
void test1() {
var pem = """
-----BEGIN CERTIFICATE-----
MIHrMIGeoAMCAQICFF4UkhlALvGwUHfuZBulAZDim5rlMAUGAytlcDAVMRMwEQYD
VQQDDApwbGF5Z3JvdW5kMCAXDTIzMTIzMTE2MDAwMFoYDzIxMjQxMjMxMTU1OTU5
WjAVMRMwEQYDVQQDDApwbGF5Z3JvdW5kMCowBQYDK2VwAyEAl1mgT4NWO98CmI8L
BfKUV7TU9OQUdBDEOqgLAZyPzQkwBQYDK2VwA0EAm+Xj5Zhqk3tcSWEKEnUuSz+6
pry+jfwdMCI7dvDurDucqQAZxLavHUI3BuQNcT4ozdT7Zu0OHgSK1PQYvAFvCQ==
-----END CERTIFICATE-----
""";
var pemContent = PemContent.of(pem);
pemContent.getCertificates().forEach(System.out::println);
}
/*
TEST OK
*/
@Test
void test2() {
var pem = """
-----BEGIN CERTIFICATE-----
MIHrMIGeoAMCAQICFF4UkhlALvGwUHfuZBulAZDim5rlMAUGAytlcDAVMRMwEQYD
VQQDDApwbGF5Z3JvdW5kMCAXDTIzMTIzMTE2MDAwMFoYDzIxMjQxMjMxMTU1OTU5
WjAVMRMwEQYDVQQDDApwbGF5Z3JvdW5kMCowBQYDK2VwAyEAl1mgT4NWO98CmI8L
BfKUV7TU9OQUdBDEOqgLAZyPzQkwBQYDK2VwA0EAm+Xj5Zhqk3tcSWEKEnUuSz+6
pry+jfwdMCI7dvDurDucqQAZxLavHUI3BuQNcT4ozdT7Zu0OHgSK1PQYvAFvCQ==
-----END CERTIFICATE-----
""";
var pemContent = PemContent.of(pem);
pemContent.getCertificates().forEach(System.out::println);
}
my version: spring-boot 3.3.2
Comment From: mhalbritter
I see, thanks for the clarification. The trimming is needed indeed.
Comment From: wilkinsona
We discussed this today and we're going to try stripping out the unwanted whitespace in private PemContent(String text) constructor. We should also check that isPresentInText(String text) works with unwanted whitespace.