Skip to content

Commit 547d469

Browse files
authored
Merge pull request #204 from CyberSource/feature/add-batch-api-pgp-mtls
Feature/add batch api pgp mtls
2 parents 03cd571 + f2973ae commit 547d469

File tree

3 files changed

+129
-64
lines changed

3 files changed

+129
-64
lines changed

src/main/java/Api/BatchUploadwithMTLSApi.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.File;
44
import java.security.PrivateKey;
55
import java.security.cert.X509Certificate;
6+
import java.util.Collection;
67

78
import org.apache.logging.log4j.LogManager;
89
import org.apache.logging.log4j.Logger;
@@ -30,9 +31,9 @@ public class BatchUploadwithMTLSApi {
3031
* @param inputFile The file to be uploaded.
3132
* @param environmentHostname The environment hostname (e.g., secure-batch-test.cybersource.com).
3233
* @param pgpEncryptionCertPath Path to the PGP encryption certificate.
33-
* @param keystorePath Path to the JKS keystore file.
34+
* @param keystorePath Path to the JKS keystore file containing client certificates.
3435
* @param keystorePassword Password for the keystore.
35-
* @param truststorePath Path to the truststore file.
36+
* @param truststorePath Path to the JKS truststore file containing trusted server certificates. <b>Optional</b>: Can be <code>null</code> if not required.
3637
* @param truststorePassword Password for the truststore.
3738
* @return ApiResponse containing the server response as a String.
3839
* @throws ApiException If an API error occurs.
@@ -56,9 +57,9 @@ public ApiResponse<String> uploadBatchAPI(File inputFile, String environmentHost
5657
* @param inputFile The file to be uploaded.
5758
* @param environmentHostname The environment hostname (e.g., api.cybersource.com).
5859
* @param pgpEncryptionCertPath Path to the PGP encryption certificate.
59-
* @param clientCertP12FilePath Path to the PKCS#12 client certificate file.
60+
* @param clientCertP12FilePath Path to the PKCS#12 client certificate file (.p12 or .pfx).
6061
* @param clientCertP12Password Password for the PKCS#12 client certificate.
61-
* @param serverTrustCertPath Path to the server trust certificate.
62+
* @param serverTrustCertPath Path to the server trust certificate(s) in PEM format. <b>Optional</b>: Can be <code>null</code> if not required.
6263
* @return ApiResponse containing the server response as a String.
6364
* @throws ApiException If an API error occurs.
6465
* @throws Exception If a general error occurs.
@@ -83,20 +84,20 @@ public ApiResponse<String> uploadBatchAPI(File inputFile, String environmentHost
8384
* @param pgpPublicKey The PGP public key for encryption.
8485
* @param clientPrivateKey The client's private key.
8586
* @param clientCert The client's X509 certificate.
86-
* @param serverTrustCert The server's trust X509 certificate.
87+
* @param serverTrustCerts A collection of server's trusted X509 certificates (can be a certificate chain). <b>Optional</b>: Can be <code>null</code> or empty if not required.
8788
* @return ApiResponse containing the server response as a String.
8889
* @throws ApiException If an API error occurs.
8990
* @throws Exception If a general error occurs.
9091
*/
91-
public ApiResponse<String> uploadBatchAPI(File inputFile, String environmentHostname, PGPPublicKey pgpPublicKey, PrivateKey clientPrivateKey, X509Certificate clientCert , X509Certificate serverTrustCert) throws ApiException, Exception {
92+
public ApiResponse<String> uploadBatchAPI(File inputFile, String environmentHostname, PGPPublicKey pgpPublicKey, PrivateKey clientPrivateKey, X509Certificate clientCert , Collection<X509Certificate> serverTrustCerts) throws ApiException, Exception {
9293
logger.info("Starting batch upload with client private key and certs for given file");
93-
BatchUploadUtility.validateBatchApiKeysInputs(inputFile, environmentHostname, pgpPublicKey, clientPrivateKey, clientCert, serverTrustCert);
94+
BatchUploadUtility.validateBatchApiKeysInputs(inputFile, environmentHostname, pgpPublicKey, clientPrivateKey, clientCert, serverTrustCerts);
9495
String endpoint = "/pts/v1/transaction-batch-upload";
9596
String endpointUrl = BatchUploadUtility.getEndpointUrl(environmentHostname, endpoint);
9697
byte[] encryptedPgpBytes = PgpEncryptionUtility.handlePGPEncrypt(inputFile, pgpPublicKey);
9798
return MutualAuthUploadUtility.handleUploadOperationUsingPrivateKeyAndCerts(
9899
encryptedPgpBytes, endpointUrl, inputFile.getName(),
99-
clientPrivateKey, clientCert, serverTrustCert
100+
clientPrivateKey, clientCert, serverTrustCerts
100101
);
101102
}
102103

src/main/java/utilities/pgpBatchUpload/BatchUploadUtility.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import java.security.cert.CertificateException;
1313
import java.security.cert.CertificateFactory;
1414
import java.security.cert.X509Certificate;
15+
import java.util.ArrayList;
16+
import java.util.Collection;
1517
import java.util.Iterator;
18+
import java.util.List;
1619

1720
import org.apache.commons.lang3.StringUtils;
1821
import org.apache.logging.log4j.LogManager;
@@ -33,21 +36,27 @@ public class BatchUploadUtility {
3336

3437
private static final Logger logger = LogManager.getLogger(BatchUploadUtility.class);
3538
private static final long MAX_FILE_SIZE_BYTES = 75 * 1024 * 1024;
36-
37-
/**
38-
* Loads an X509 certificate from a PEM file.
39+
40+
/**
41+
* Loads X509 certificates from a PEM file.
3942
*
4043
* @param certFilePath The file path to the PEM certificate file.
41-
* @return The loaded X509Certificate object.
44+
* @return The loaded X509Certificate(s) as a Collection.
4245
* @throws CertificateException If the certificate cannot be parsed or is invalid.
4346
* @throws IOException If the file cannot be read or does not exist.
4447
*/
45-
public static X509Certificate loadCertificateFromPemFile(String certFilePath) throws CertificateException, IOException {
46-
try (FileInputStream inStream = new FileInputStream(certFilePath)) {
47-
CertificateFactory cf = CertificateFactory.getInstance("X.509");
48-
return (X509Certificate) cf.generateCertificate(inStream);
49-
}
50-
}
48+
public static Collection<X509Certificate> loadCertificatesFromPemFile(String certFilePath) throws CertificateException, IOException {
49+
try (FileInputStream inStream = new FileInputStream(certFilePath)) {
50+
CertificateFactory cf = CertificateFactory.getInstance("X.509");
51+
Collection<? extends java.security.cert.Certificate> certs = cf.generateCertificates(inStream);
52+
// Cast to X509Certificate
53+
List<X509Certificate> x509Certs = new ArrayList<>();
54+
for (java.security.cert.Certificate cert : certs) {
55+
x509Certs.add((X509Certificate) cert);
56+
}
57+
return x509Certs;
58+
}
59+
}
5160

5261
/**
5362
* Reads a PGP public key from the specified file.
@@ -114,7 +123,8 @@ public static void validateBatchApiJKSInputs(File inputFile, String environmentH
114123
}
115124
validatePathAndFile(pgpEncryptionCertPath, "PGP Encryption Cert Path");
116125
validatePathAndFile(keystorePath, "Keystore Path");
117-
validatePathAndFile(truststorePath, "Truststore Path");
126+
if (!StringUtils.isEmpty(truststorePath))
127+
validatePathAndFile(truststorePath, "Truststore Path");
118128
}
119129

120130
/**
@@ -135,7 +145,8 @@ public static void validateBatchApiP12Inputs(File inputFile, String environmentH
135145
}
136146
validatePathAndFile(pgpEncryptionCertPath, "PGP Encryption Cert Path");
137147
validatePathAndFile(clientCertP12FilePath, "Client Cert P12 File Path");
138-
validatePathAndFile(serverTrustCertPath, "Server Trust Cert Path");
148+
if (!StringUtils.isEmpty(serverTrustCertPath))
149+
validatePathAndFile(serverTrustCertPath, "Server Trust Cert Path");
139150
}
140151

141152
/**
@@ -149,7 +160,7 @@ public static void validateBatchApiP12Inputs(File inputFile, String environmentH
149160
* @param serverTrustCert The server trust X509 certificate.
150161
* @throws Exception If any validation fails.
151162
*/
152-
public static void validateBatchApiKeysInputs(File inputFile, String environmentHostname, PGPPublicKey pgpPublicKey, PrivateKey clientPrivateKey, X509Certificate clientCert , X509Certificate serverTrustCert) throws Exception{
163+
public static void validateBatchApiKeysInputs(File inputFile, String environmentHostname, PGPPublicKey pgpPublicKey, PrivateKey clientPrivateKey, X509Certificate clientCert , Collection<X509Certificate> serverTrustCert) throws Exception{
153164
validateInputFile(inputFile);
154165
if(StringUtils.isEmpty(environmentHostname)) {
155166
logger.error("Environment Host Name for Batch Upload API cannot be null or empty.");
@@ -158,7 +169,7 @@ public static void validateBatchApiKeysInputs(File inputFile, String environment
158169
if (pgpPublicKey == null) throw new IllegalArgumentException("PGP Public Key is null");
159170
if (clientPrivateKey == null) throw new IllegalArgumentException("Client Private Key is null");
160171
if (clientCert == null) throw new IllegalArgumentException("Client Certificate is null");
161-
if (serverTrustCert == null) throw new IllegalArgumentException("Server Trust Certificate is null");
172+
//if (serverTrustCert == null) throw new IllegalArgumentException("Server Trust Certificate is null"); serverTrustCert is optional so can be null
162173
}
163174

164175
/**

0 commit comments

Comments
 (0)