55import java .security .KeyStore .LoadStoreParameter ;
66import java .security .KeyStore .ProtectionParameter ;
77
8+ import org .bouncycastle .asn1 .ASN1ObjectIdentifier ;
9+ import org .bouncycastle .asn1 .DERNull ;
10+ import org .bouncycastle .asn1 .pkcs .PBKDF2Params ;
11+ import org .bouncycastle .asn1 .pkcs .PBMAC1Params ;
12+ import org .bouncycastle .asn1 .pkcs .PKCSObjectIdentifiers ;
13+ import org .bouncycastle .asn1 .x509 .AlgorithmIdentifier ;
14+ import org .bouncycastle .internal .asn1 .oiw .OIWObjectIdentifiers ;
15+ import org .bouncycastle .util .Arrays ;
16+
817/**
918 * LoadStoreParameter to allow for additional config with PKCS12 files.
1019 * <p>
@@ -18,6 +27,123 @@ public class PKCS12StoreParameter
1827 private final ProtectionParameter protectionParameter ;
1928 private final boolean forDEREncoding ;
2029 private final boolean overwriteFriendlyName ;
30+ private final AlgorithmIdentifier macAlgorithm ;
31+
32+ public static class PBMAC1WithPBKDF2Builder
33+ {
34+ private int iterationCount = 16384 ;
35+ private byte [] salt = null ;
36+ private int keySizeinBits = 256 ;
37+ private ASN1ObjectIdentifier prf = PKCSObjectIdentifiers .id_hmacWithSHA256 ;
38+ private ASN1ObjectIdentifier mac = PKCSObjectIdentifiers .id_hmacWithSHA512 ;
39+
40+ PBMAC1WithPBKDF2Builder ()
41+ {
42+
43+ }
44+
45+ public PBMAC1WithPBKDF2Builder setIterationCount (int iterationCount )
46+ {
47+ this .iterationCount = iterationCount ;
48+
49+ return this ;
50+ }
51+
52+ public PBMAC1WithPBKDF2Builder setSalt (byte [] salt )
53+ {
54+ this .salt = Arrays .clone (salt );
55+
56+ return this ;
57+ }
58+
59+ public PBMAC1WithPBKDF2Builder setKeySize (int keySizeinBits )
60+ {
61+ this .keySizeinBits = keySizeinBits ;
62+
63+ return this ;
64+ }
65+
66+ public PBMAC1WithPBKDF2Builder setPrf (ASN1ObjectIdentifier prf )
67+ {
68+ this .prf = prf ;
69+
70+ return this ;
71+ }
72+
73+ public PBMAC1WithPBKDF2Builder setMac (ASN1ObjectIdentifier mac )
74+ {
75+ this .mac = mac ;
76+
77+ return this ;
78+ }
79+
80+ public AlgorithmIdentifier build ()
81+ {
82+ if (salt != null )
83+ {
84+ throw new IllegalStateException ("salt must be non-null" );
85+ }
86+
87+ return new AlgorithmIdentifier (PKCSObjectIdentifiers .id_PBMAC1 , new PBMAC1Params (new AlgorithmIdentifier (PKCSObjectIdentifiers .id_PBKDF2 , new PBKDF2Params (salt , iterationCount , keySizeinBits , new AlgorithmIdentifier (prf ))),
88+ new AlgorithmIdentifier (mac )));
89+ }
90+ }
91+
92+ public static PBMAC1WithPBKDF2Builder pbmac1WithPBKDF2Builder ()
93+ {
94+ return new PBMAC1WithPBKDF2Builder ();
95+ }
96+
97+ public static class Builder
98+ {
99+ private final OutputStream out ;
100+ private final ProtectionParameter protectionParameter ;
101+ private boolean forDEREncoding = true ;
102+ private boolean overwriteFriendlyName = true ;
103+ private AlgorithmIdentifier macAlgorithm = new AlgorithmIdentifier (OIWObjectIdentifiers .idSHA1 , DERNull .INSTANCE );
104+
105+ private Builder (OutputStream out , ProtectionParameter protectionParameter )
106+ {
107+ this .out = out ;
108+ this .protectionParameter = protectionParameter ;
109+ }
110+
111+ public Builder setDEREncoding (boolean enable )
112+ {
113+ this .forDEREncoding = enable ;
114+
115+ return this ;
116+ }
117+
118+ public Builder setOverwriteFriendlyName (boolean enable )
119+ {
120+ this .overwriteFriendlyName = enable ;
121+
122+ return this ;
123+ }
124+
125+ public Builder setMacAlgorithm (AlgorithmIdentifier macAlgorithm )
126+ {
127+ this .macAlgorithm = macAlgorithm ;
128+
129+ return this ;
130+ }
131+
132+ public PKCS12StoreParameter build ()
133+ {
134+ return new PKCS12StoreParameter (out , protectionParameter , forDEREncoding , overwriteFriendlyName , macAlgorithm );
135+ }
136+ }
137+
138+ public static Builder builder (OutputStream out , char [] password )
139+ {
140+ return builder (out , new KeyStore .PasswordProtection (password ));
141+ }
142+
143+ public static Builder builder (OutputStream out , ProtectionParameter protectionParameter )
144+ {
145+ return new Builder (out , protectionParameter );
146+ }
21147
22148 public PKCS12StoreParameter (OutputStream out , char [] password )
23149 {
@@ -33,6 +159,7 @@ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREnc
33159 {
34160 this (out , new KeyStore .PasswordProtection (password ), forDEREncoding , true );
35161 }
162+
36163 public PKCS12StoreParameter (OutputStream out , ProtectionParameter protectionParameter , boolean forDEREncoding )
37164 {
38165 this (out , protectionParameter , forDEREncoding , true );
@@ -44,11 +171,17 @@ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREnc
44171 }
45172
46173 public PKCS12StoreParameter (OutputStream out , ProtectionParameter protectionParameter , boolean forDEREncoding , boolean overwriteFriendlyName )
174+ {
175+ this (out , protectionParameter , forDEREncoding , overwriteFriendlyName , new AlgorithmIdentifier (OIWObjectIdentifiers .idSHA1 , DERNull .INSTANCE ));
176+ }
177+
178+ private PKCS12StoreParameter (OutputStream out , ProtectionParameter protectionParameter , boolean forDEREncoding , boolean overwriteFriendlyName , AlgorithmIdentifier macAlgorithm )
47179 {
48180 this .out = out ;
49181 this .protectionParameter = protectionParameter ;
50182 this .forDEREncoding = forDEREncoding ;
51183 this .overwriteFriendlyName = overwriteFriendlyName ;
184+ this .macAlgorithm = macAlgorithm ;
52185 }
53186
54187 public OutputStream getOutputStream ()
@@ -81,4 +214,9 @@ public boolean isOverwriteFriendlyName()
81214 {
82215 return overwriteFriendlyName ;
83216 }
217+
218+ public AlgorithmIdentifier getMacAlgorithm ()
219+ {
220+ return macAlgorithm ;
221+ }
84222}
0 commit comments