1818import static com .google .common .truth .Truth .assertThat ;
1919import static com .google .common .truth .Truth .assertWithMessage ;
2020
21- import com .google .cloud .kms .v1 .CreateKeyRingRequest ;
22- import com .google .cloud .kms .v1 .CryptoKey ;
23- import com .google .cloud .kms .v1 .CryptoKey .CryptoKeyPurpose ;
24- import com .google .cloud .kms .v1 .CryptoKeyVersion ;
25- import com .google .cloud .kms .v1 .CryptoKeyVersion .CryptoKeyVersionAlgorithm ;
26- import com .google .cloud .kms .v1 .CryptoKeyVersionName ;
27- import com .google .cloud .kms .v1 .CryptoKeyVersionTemplate ;
28- import com .google .cloud .kms .v1 .KeyManagementServiceClient ;
29- import com .google .cloud .kms .v1 .KeyRing ;
30- import com .google .cloud .kms .v1 .KeyRingName ;
31- import com .google .cloud .kms .v1 .LocationName ;
3221import com .google .cloud .security .privateca .v1 .CaPoolName ;
3322import com .google .cloud .security .privateca .v1 .Certificate ;
3423import com .google .cloud .security .privateca .v1 .CertificateAuthority ;
3827import com .google .protobuf .ByteString ;
3928import java .io .ByteArrayOutputStream ;
4029import java .io .IOException ;
30+ import java .io .OutputStreamWriter ;
4131import java .io .PrintStream ;
32+ import java .security .KeyPair ;
33+ import java .security .KeyPairGenerator ;
34+ import java .security .NoSuchAlgorithmException ;
35+ import java .security .NoSuchProviderException ;
36+ import java .security .Security ;
37+ import java .security .interfaces .RSAPrivateKey ;
38+ import java .security .interfaces .RSAPublicKey ;
4239import java .util .UUID ;
4340import java .util .concurrent .ExecutionException ;
4441import java .util .concurrent .TimeUnit ;
4542import java .util .concurrent .TimeoutException ;
43+ import org .bouncycastle .jce .provider .BouncyCastleProvider ;
44+ import org .bouncycastle .util .io .pem .PemObject ;
45+ import org .bouncycastle .util .io .pem .PemWriter ;
4646import org .junit .After ;
4747import org .junit .AfterClass ;
4848import org .junit .Assert ;
@@ -57,15 +57,12 @@ public class SnippetsIT {
5757
5858 private static final String PROJECT_ID = System .getenv ("GOOGLE_CLOUD_PROJECT" );
5959 private static String LOCATION ;
60- private static String KMS_LOCATION ;
6160 private static String CA_POOL_NAME ;
6261 private static String CA_POOL_NAME_DELETE ;
6362 private static String CA_NAME ;
6463 private static String CA_NAME_DELETE ;
6564 private static String CERTIFICATE_NAME ;
66- private static String KEY_RING_ID ;
67- private static String KEY_ID ;
68- private static String VERSION_ID ;
65+ private static int KEY_SIZE ;
6966
7067 private ByteArrayOutputStream stdOut ;
7168
@@ -77,24 +74,24 @@ public static void reqEnvVar(String envVarName) {
7774 }
7875
7976 @ BeforeClass
80- public static void setUp () throws InterruptedException , ExecutionException , IOException {
77+ public static void setUp ()
78+ throws IOException , ExecutionException , NoSuchProviderException , NoSuchAlgorithmException ,
79+ InterruptedException {
8180 reqEnvVar ("GOOGLE_APPLICATION_CREDENTIALS" );
8281 reqEnvVar ("GOOGLE_CLOUD_PROJECT" );
8382
8483 LOCATION = "asia-south1" ;
85- KMS_LOCATION = "global" ;
8684 CA_POOL_NAME = "ca-pool-" + UUID .randomUUID ().toString ();
8785 CA_POOL_NAME_DELETE = "ca-pool-" + UUID .randomUUID ().toString ();
8886 CA_NAME = "ca-name-" + UUID .randomUUID ().toString ();
8987 CA_NAME_DELETE = "ca-name-" + UUID .randomUUID ().toString ();
9088 CERTIFICATE_NAME = "certificate-name-" + UUID .randomUUID ().toString ();
91- KEY_RING_ID = "key-ring-id-" + UUID .randomUUID ().toString ();
92- KEY_ID = "key-id-" + UUID .randomUUID ().toString ();
93- VERSION_ID = "1" ;
89+ KEY_SIZE = 2048 ; // Default key size
9490
9591 // Create CA Pool.
9692 privateca .CreateCaPool .createCaPool (PROJECT_ID , LOCATION , CA_POOL_NAME );
9793 privateca .CreateCaPool .createCaPool (PROJECT_ID , LOCATION , CA_POOL_NAME_DELETE );
94+ sleep (5 );
9895
9996 // Create and Enable Certificate Authorities.
10097 privateca .CreateCertificateAuthority .createCertificateAuthority (
@@ -105,17 +102,27 @@ public static void setUp() throws InterruptedException, ExecutionException, IOEx
105102 privateca .EnableCertificateAuthority .enableCertificateAuthority (
106103 PROJECT_ID , LOCATION , CA_POOL_NAME , CA_NAME );
107104
108- // Create Asymmetric Sign Key used to sign certificate, with Cloud KMS.
109- createKeyRing ();
110- sleep (5 );
111- createAsymmetricSignKey ();
105+ // Create an asymmetric key pair using Bouncy Castle crypto framework.
106+ KeyPair asymmetricKeyPair = createAsymmetricKeyPair ();
107+
108+ // Cast the keys to their respective components.
109+ RSAPublicKey publicKey = (RSAPublicKey ) asymmetricKeyPair .getPublic ();
110+ RSAPrivateKey privateKey = (RSAPrivateKey ) asymmetricKeyPair .getPrivate ();
111+
112+ // Construct the PemObject for public and private keys.
113+ PemObject publicKeyPemObject = new PemObject ("PUBLIC KEY" , publicKey .getEncoded ());
114+ PemObject privateKeyPemObject = new PemObject ("PRIVATE KEY" , privateKey .getEncoded ());
115+
116+ // Only the public key will be used to create the certificate.
117+ ByteString publicKeyByteString = convertToPemEncodedByteString (publicKeyPemObject );
112118
113- // Retrieve public key from Cloud KMS and Create Certificate.
114- ByteString publicKey =
115- privateca .CreateCertificate .retrievePublicKey (
116- PROJECT_ID , KMS_LOCATION , KEY_RING_ID , KEY_ID , VERSION_ID );
119+ // TODO (Developers): Save the private key by writing it to a file and
120+ // TODO (cont): use it to verify the issued certificate.
121+ ByteString privateKeyByteString = convertToPemEncodedByteString (privateKeyPemObject );
122+
123+ // Create certificate with the above generated public key.
117124 privateca .CreateCertificate .createCertificate (
118- PROJECT_ID , LOCATION , CA_POOL_NAME , CA_NAME , CERTIFICATE_NAME , publicKey );
125+ PROJECT_ID , LOCATION , CA_POOL_NAME , CA_NAME , CERTIFICATE_NAME , publicKeyByteString );
119126 sleep (5 );
120127 }
121128
@@ -125,9 +132,6 @@ public static void cleanUp() throws InterruptedException, ExecutionException, IO
125132 ByteArrayOutputStream stdOut = new ByteArrayOutputStream ();
126133 System .setOut (new PrintStream (stdOut ));
127134
128- // De-provision public key.
129- cleanupCertificateSignKey ();
130-
131135 // Delete CA and CA pool.
132136 privateca .DeleteCertificateAuthority .deleteCertificateAuthority (
133137 PROJECT_ID , LOCATION , CA_POOL_NAME , CA_NAME );
@@ -138,71 +142,34 @@ public static void cleanUp() throws InterruptedException, ExecutionException, IO
138142 System .setOut (null );
139143 }
140144
141- // Create a new key ring.
142- public static void createKeyRing () throws IOException {
143- // Initialize client that will be used to send requests. This client only
144- // needs to be created once, and can be reused for multiple requests. After
145- // completing all of your requests, call the "close" method on the client to
146- // safely clean up any remaining background resources.
147- try (KeyManagementServiceClient client = KeyManagementServiceClient .create ()) {
148- // Build the parent name from the project and location.
149- LocationName locationName = LocationName .of (PROJECT_ID , KMS_LOCATION );
150-
151- // Build the key ring to create.
152- KeyRing keyRing = KeyRing .newBuilder ().setName (locationName .toString ()).build ();
153-
154- // Create the key ring.
155- KeyRing createdKeyRing =
156- client .createKeyRing (
157- CreateKeyRingRequest .newBuilder ()
158- .setParent (locationName .toString ())
159- .setKeyRing (keyRing )
160- .setKeyRingId (KEY_RING_ID )
161- .build ());
162- System .out .printf ("Created key ring: %s%n" , createdKeyRing .getName ());
163- }
145+ // Wait for the specified amount of time.
146+ public static void sleep (int seconds ) throws InterruptedException {
147+ TimeUnit .SECONDS .sleep (seconds );
164148 }
165149
166- // Create a new asymmetric key for the purpose of signing and verifying data.
167- public static void createAsymmetricSignKey () throws IOException {
168- // Initialize client that will be used to send requests. This client only
169- // needs to be created once, and can be reused for multiple requests. After
170- // completing all of your requests, call the "close" method on the client to
171- // safely clean up any remaining background resources.
172- try (KeyManagementServiceClient client = KeyManagementServiceClient .create ()) {
173- // Build the parent name from the project, location, and key ring.
174- KeyRingName keyRingName = KeyRingName .of (PROJECT_ID , KMS_LOCATION , KEY_RING_ID );
175-
176- // Build the asymmetric key to create.
177- CryptoKey key =
178- CryptoKey .newBuilder ()
179- .setPurpose (CryptoKeyPurpose .ASYMMETRIC_SIGN )
180- .setVersionTemplate (
181- CryptoKeyVersionTemplate .newBuilder ()
182- .setAlgorithm (CryptoKeyVersionAlgorithm .RSA_SIGN_PKCS1_2048_SHA256 ))
183- .build ();
184-
185- // Create the key.
186- CryptoKey createdKey = client .createCryptoKey (keyRingName , KEY_ID , key );
187- System .out .printf ("Created asymmetric key: %s%n" , createdKey .getName ());
188- }
189- }
150+ // Create an asymmetric key pair to be used in certificate signing.
151+ public static KeyPair createAsymmetricKeyPair ()
152+ throws NoSuchAlgorithmException , NoSuchProviderException {
153+ Security .addProvider (new BouncyCastleProvider ());
190154
191- public static void cleanupCertificateSignKey () throws IOException , InterruptedException {
192- try (KeyManagementServiceClient client = KeyManagementServiceClient .create ()) {
193- CryptoKeyVersionName cryptoKeyVersionName =
194- CryptoKeyVersionName .of (PROJECT_ID , KMS_LOCATION , KEY_RING_ID , KEY_ID , VERSION_ID );
195- // Destroy the crypto key version.
196- CryptoKeyVersion cryptoKeyVersion = client .destroyCryptoKeyVersion (cryptoKeyVersionName );
197- sleep (5 );
198- // If the response has destroy time, then the version is successfully destroyed.
199- Assert .assertTrue (cryptoKeyVersion .hasDestroyTime ());
200- }
155+ // Generate the key pair with RSA algorithm using Bouncy Castle (BC).
156+ KeyPairGenerator generator = KeyPairGenerator .getInstance ("RSA" , "BC" );
157+ generator .initialize (KEY_SIZE );
158+ KeyPair keyPair = generator .generateKeyPair ();
159+
160+ return keyPair ;
201161 }
202162
203- // Wait for the specified amount of time.
204- public static void sleep (int seconds ) throws InterruptedException {
205- TimeUnit .SECONDS .sleep (seconds );
163+ // Convert the encoded PemObject to ByteString.
164+ public static ByteString convertToPemEncodedByteString (PemObject pemEncodedKey )
165+ throws IOException {
166+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ();
167+ PemWriter pemWriter = new PemWriter (new OutputStreamWriter (byteArrayOutputStream ));
168+ pemWriter .writeObject (pemEncodedKey );
169+ pemWriter .close ();
170+ ByteString keyByteString = ByteString .copyFrom (byteArrayOutputStream .toByteArray ());
171+
172+ return keyByteString ;
206173 }
207174
208175 @ Before
0 commit comments