mirror of
https://github.com/sneakybugmaster/mailsender.git
synced 2026-11-10 19:48:49 +00:00
Add certificate validation and PGP/MIME encryption; rename to pro.thinhha.mailsender
- validation: CertificateValidator checks revocation, expiry, matching user ID, a valid communications encryption subkey and the algorithm policy; uses the earlier expiry when PGPainless and Bouncy Castle disagree - crypto: PgpEncryptor (ASCII armor, hidden recipients for Bcc) - mime: PgpMimeEncryptor builds RFC 3156 multipart/encrypted from the whole CRLF-canonical inner entity, keeping envelope headers in the clear - autoconfigure: validator and encryptor beans - demo: encrypts when a valid key is found, plaintext otherwise - rename groupId and Java packages to pro.thinhha.mailsender Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G71TQ5jDETVwdUJxGAwaiT
This commit is contained in:
44 files changed
+958
-142
No files matched your search
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.github.sneakybugmaster.mailsender</groupId>
|
||||
<groupId>pro.thinhha.mailsender</groupId>
|
||||
<artifactId>mailsender-parent</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.github.sneakybugmaster.mailsender</groupId>
|
||||
<groupId>pro.thinhha.mailsender</groupId>
|
||||
<artifactId>mailsender-pgp-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+34
-12
@@ -1,4 +1,4 @@
|
||||
package io.github.sneakybugmaster.mailsender.pgp.autoconfigure;
|
||||
package pro.thinhha.mailsender.pgp.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -18,19 +18,23 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.CachingKeyDiscovery;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.Certificates;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.CompositeKeyDiscovery;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.HostResolver;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.HttpWkdFetcher;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.KeyDiscovery;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.StaticKeyDiscovery;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.WkdFetcher;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.WkdKeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.crypto.PgpEncryptor;
|
||||
import pro.thinhha.mailsender.pgp.discovery.CachingKeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.discovery.Certificates;
|
||||
import pro.thinhha.mailsender.pgp.discovery.CompositeKeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.discovery.HostResolver;
|
||||
import pro.thinhha.mailsender.pgp.discovery.HttpWkdFetcher;
|
||||
import pro.thinhha.mailsender.pgp.discovery.KeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.discovery.StaticKeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.discovery.WkdFetcher;
|
||||
import pro.thinhha.mailsender.pgp.discovery.WkdKeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.mime.PgpMimeEncryptor;
|
||||
import pro.thinhha.mailsender.pgp.validation.CertificateValidator;
|
||||
|
||||
/**
|
||||
* Key discovery beans: pinned keys first, then WKD behind a cache. The primary {@link KeyDiscovery} bean is the
|
||||
* combined chain; {@link CachingKeyDiscovery} is exposed separately so applications can evict entries.
|
||||
* Key discovery (pinned keys first, then WKD behind a cache), certificate validation and PGP/MIME encryption beans.
|
||||
* The primary {@link KeyDiscovery} bean is the combined chain; {@link CachingKeyDiscovery} is exposed separately so
|
||||
* applications can evict entries.
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(PgpMailProperties.class)
|
||||
@@ -75,6 +79,24 @@ public class PgpMailAutoConfiguration {
|
||||
return new CompositeKeyDiscovery(chain);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
CertificateValidator pgpCertificateValidator() {
|
||||
return new CertificateValidator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
PgpEncryptor pgpEncryptor() {
|
||||
return new PgpEncryptor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
PgpMimeEncryptor pgpMimeEncryptor(PgpEncryptor encryptor) {
|
||||
return new PgpMimeEncryptor(encryptor);
|
||||
}
|
||||
|
||||
private static List<OpenPGPCertificate> read(String email, Resource resource) {
|
||||
try (InputStream in = resource.getInputStream()) {
|
||||
List<OpenPGPCertificate> certificates = Certificates.parse(in.readAllBytes());
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package io.github.sneakybugmaster.mailsender.pgp.autoconfigure;
|
||||
package pro.thinhha.mailsender.pgp.autoconfigure;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
@@ -8,7 +8,7 @@ import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.WkdFallback;
|
||||
import pro.thinhha.mailsender.pgp.discovery.WkdFallback;
|
||||
|
||||
/**
|
||||
* {@code mail.pgp.*} configuration.
|
||||
+1
-1
@@ -1 +1 @@
|
||||
io.github.sneakybugmaster.mailsender.pgp.autoconfigure.PgpMailAutoConfiguration
|
||||
pro.thinhha.mailsender.pgp.autoconfigure.PgpMailAutoConfiguration
|
||||
+11
-8
@@ -1,4 +1,4 @@
|
||||
package io.github.sneakybugmaster.mailsender.pgp.autoconfigure;
|
||||
package pro.thinhha.mailsender.pgp.autoconfigure;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -13,12 +13,14 @@ import org.pgpainless.PGPainless;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.CachingKeyDiscovery;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.DiscoveryResult;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.DiscoverySource;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.KeyDiscovery;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.WkdFallback;
|
||||
import io.github.sneakybugmaster.mailsender.pgp.discovery.WkdFetcher;
|
||||
import pro.thinhha.mailsender.pgp.discovery.CachingKeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.discovery.DiscoveryResult;
|
||||
import pro.thinhha.mailsender.pgp.discovery.DiscoverySource;
|
||||
import pro.thinhha.mailsender.pgp.discovery.KeyDiscovery;
|
||||
import pro.thinhha.mailsender.pgp.discovery.WkdFallback;
|
||||
import pro.thinhha.mailsender.pgp.discovery.WkdFetcher;
|
||||
import pro.thinhha.mailsender.pgp.mime.PgpMimeEncryptor;
|
||||
import pro.thinhha.mailsender.pgp.validation.CertificateValidator;
|
||||
|
||||
class PgpMailAutoConfigurationTest {
|
||||
|
||||
@@ -31,7 +33,8 @@ class PgpMailAutoConfigurationTest {
|
||||
@Test
|
||||
void createsDiscoveryChainWithDefaults() {
|
||||
runner.run(context -> {
|
||||
assertThat(context).hasSingleBean(WkdFetcher.class).hasSingleBean(CachingKeyDiscovery.class);
|
||||
assertThat(context).hasSingleBean(WkdFetcher.class).hasSingleBean(CachingKeyDiscovery.class)
|
||||
.hasSingleBean(CertificateValidator.class).hasSingleBean(PgpMimeEncryptor.class);
|
||||
assertThat(context.getBean(KeyDiscovery.class)).isNotInstanceOf(CachingKeyDiscovery.class);
|
||||
|
||||
PgpMailProperties properties = context.getBean(PgpMailProperties.class);
|
||||
Reference in new issue
Block a user