Creating keystores and truststores using the Edge management API

This document describes how to create, modify, and delete keystores and truststores for Edge for the Cloud and for Edge for the Private Cloud versions 4.18.01 and later.

Introduction

To configure functionality that relies on public key infrastructure, such as TLS, you need to create keystores and truststores that provide the necessary keys and digital certificates.

For an introduction to keystores, truststore, and aliases, see Keystores and Truststores.

Create a keystore

A keystore is specific to an environment in your organization, for example the test or prod environment. Therefore, if you want to test the keystore in a test environment before deploying it to your production environment, you must create it in both environments.

To create a keystore in an environment:

  1. Use the API call in this section to create the keystore.
  2. Create an alias and upload a cert/key pair to the alias. The way you upload the cert and key is based on the format of the cert/key pair. The following sections describe how to upload each type of cert/key pair:

To create a keystore specify the keystore name to the Create a Keystore or Truststore API. The keystore name can only contain alphanumeric characters:

curl -X POST -u orgAdminEmail:password -H "Content-Type: text/xml" \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores \
-d '<KeyStore name="myKeystore"/>'

Sample response:

{
 "certs" : [ ],
 "keys" : [ ],
 "name" : "myKeystore"
}

Upload a cert and key as a JAR file

You must first create a JAR file with your private key, certificate, and a manifest. The JAR file must contain the following files and directories:

/META-INF/descriptor.properties
myCert.pem
myKey.pem

A keystore JAR can contain only one certificate. If you have a certificate chain, all certs in the chain must be appended into a single PEM file, where the last certificate is signed by a CA. The certs must be appended to the PEM file in the correct order, with an empty line between each cert, meaning:

cert -> intermediate cert(1) -> intermediate cert(2) -> … -> root

In the directory containing your key pair and certificate, create a directory called /META-INF. Then, create a file called descriptor.properties in /META-INF with the following contents:

certFile={myCertificate}.pem
keyFile={myKey}.pem

Generate the JAR file containing your key pair and certificate:

jar -cf myKeystore.jar myCert.pem myKey.pem

Add descriptor.properties to your JAR file:

jar -uf myKeystore.jar META-INF/descriptor.properties

You can now upload your JAR files that contain a cert and private key by using the Create an alias from a JAR or PKCS file API:

curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" -F file="@myKeystore.jar" -F password={key_pword} \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?alias={alias_name}&format=keycertjar"

where the -F option specifies the path to the JAR file.

In this call, you specify:

  • alias_name - Identifies the certificate and key in the key store. When you create a virtual host, you reference the certificate and key by its alias name.
  • key_pword - The password for the private key. Omit this parameter if the private key has no password.

Verify that your keystore uploaded properly:

curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}

Sample response:

{  
 "certs" : [ "myCertificate" ],
 "keys" : [ "myKey" ],
 "name" : "myKeystore"
}

Upload a cert and key as PEM files

Upload PEM files that contain a cert and private key by using the Create an alias from a certificate PEM file API:

curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" -F keyFile="@server.key" -F certFile="@signed.crt" \
-F password={key_pword} \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?alias={alias_name}&format=keycertfile"

where the -F option specifies the path to the JAR file.

In this call, you specify:

  • alias_name - Identifies the certificate and key in the key store. When you create a virtual host, you reference the certificate and key by its alias name.
  • key_pword - The password for the private key. Omit this parameter if the private key has no password.

Verify that your keystore uploaded properly:

curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}

Sample response:

{  
 "certs" : [ "myCertificate" ],
 "keys" : [ "myKey" ],
 "name" : "myKeystore"
}

Upload a cert and key as a PKCS12/PFX file

Upload a PKCS12/PFX file that contains a cert and private key by using the Create an alias from a JAR or PKCS file API:

curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" \
-F file="@myKeystore.p12" -F password={key_pword} \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?alias={alias_name}&format=pkcs12"

where the -F option specifies the path to the P12 file.

In this call, you specify:

  • alias_name - Identifies the certificate and key in the key store. When you create a virtual host, you reference the certificate and key by its alias name.
  • key_pword - The password for the private key. Omit this parameter if the private key has no password.

Verify that your keystore uploaded properly:

curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}

Sample response:

{  
 "certs" : [ "myCertificate" ],
 "keys" : [ "myKey" ],
 "name" : "myKeystore"
}

Create and upload a self-signed cert and key

You can use the Create an alias by generating a self-signed certificate API to create a self-signed cert and key and upload them to an alias. The following call specifies only the required information to create the self-signed cert. You can modify this call to add additional information:

curl -u orgAdminEmail:password -X POST --header "Content-Type: application/json"  \
-d "{
    "alias": "selfsigned",
    "subject": {
        "commonName": "mycert"
    }
}" \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?format=selfsignedcert"

The response should appear as:

{
  "alias": "selfsigned",
  "certsInfo": {
    "certInfo": [
      {
        "basicConstraints": "CA:FALSE",
        "expiryDate": 1491497204000,
        "isValid": "Yes",
        "issuer": "CN=mycert",
        "publicKey": "RSA Public Key, 2048 bits",
        "serialNumber": "00:d1:b4:78:e1",
        "sigAlgName": "SHA256withRSA",
        "subject": "CN=mycert",
        "subjectAlternativeNames": [],
        "validFrom": 1459961204000,
        "version": 3
      }
    ],
    "certName": "selfsigned-cert"
  },
  "keyName": "selfsigned"
}

Create a truststore

The APIs that you use to create a truststore is the same as used to create a keystore. The only difference is that you only upload a cert file, as a PEM file, to the truststore.

If the cert is part of a chain, then you must either upload all certs in the chain separately to the truststore, or create a single file containing all the certs. You must insert an empty line between each cert in the file.

The final certificate is typically signed by the certificate issuer. For example, in the truststore, you upload a client certificate,client_cert_1, and the client certificate issuer's certificate, ca_cert.

During two-way TLS authentication, client authentication succeeds when the server sends client_cert_1 to the client as part of the TLS handshaking process.

Alternatively, you have a second cert, client_cert_2, signed by the same cert, ca_cert. However, you do not upload client_cert_2 to the truststore. The truststore still contains client_cert_1 and ca_cert.

When the server passes client_cert_2 as part of TLS handshaking, the request succeeds. This is because Edge allows TLS verification to succeed when client_cert_2 does not exist in the truststore but was signed by the a cert that exists in the truststore. If you remove the CA certificate, ca_cert, from the truststore then TLS verification fails.

Create an empty truststore in the environment by using Create a Keystore or Truststore, the same API that you use to create a keystore:

curl -u orgAdminEmail:password -X POST -H "Content-Type: text/xml" \
-d '<KeyStore name="myTruststore"/>' \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores

After you create the truststore, upload the certificate as a PEM file to the truststore by using the Create an alias from a certificate PEM file API:

curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" -F certFile="@cert.pem" \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/myTruststore/aliases?alias=myTruststore&format=keycertfile"

where the -F option specifies the path to the PEM file.

Get details about an existing keystore or truststore

Check your environment for any existing keystores by using the List Keystores and Truststores API:

curl -u orgAdminEmail:password -X GET \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores

For cloud customers, a default keystore is provided for free trial organizations in both the test and prod environments. You should see the following results for this call for both environments:

[ "freetrial" ]

You can use this default keystore to test your APIs, and push your APIs to production, but you typically create your own keystore, with your own cert and key, before you deploy to production.

For Private Cloud customers, the returned array is empty until you create your first keystore.

Check the contents of the keystore by using the Get a Keystore or Truststore API. For a cloud customer, you should see a single server TLS certificate--the default certificate that Apigee Edge provides for free trial accounts.

curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/freetrial

The response should appear as:

{
 "certs" : [ "wildcard.apigee.net.crt" ],
 "keys" : [ "freetrial" ],
 "name" : "freetrial"
}

Get details about an alias

Get a list of all aliases for an keystores by using the List aliases API:

curl -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases"

The response should appear as:

[
  "alias1",
  "alias2",
  "alias3",
]

To get all information about an alias, such as expiration date and issuer, use the Get alias API and specify the alias name:

curl  -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases/{alias_name}"

The response should appear as:

{
  "alias": "alias1",
  "certsInfo": {
    "certInfo": [
      {
        "basicConstraints": "CA:TRUE",
        "expiryDate": 1459371335000,
        "isValid": "No",
        "issuer": "EMAILADDRESS=foo@bar.com, CN=smg, OU=doc, O=Internet Widgits Pty Ltd, L=noho, ST=Some-State, C=AU",
        "publicKey": "RSA Public Key, 1024 bits",
        "serialNumber": "00:86:a0:9b:5b:91:a9:fe:92",
        "sigAlgName": "SHA256withRSA",
        "subject": "EMAILADDRESS=foo@bar.com, CN=smg, OU=doc, O=Internet Widgits Pty Ltd, L=noho, ST=Some-State, C=AU",
        "subjectAlternativeNames": [],
        "validFrom": 1456779335000,
        "version": 3
      }
    ],
    "certName": "new\-cert"
  },
  "keyName": "newssl20"
}

To download the cert for an alias, use the Export a certificate for an alias API:

curl -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/e/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases/{alias_name}/certificate"

The response should appear as:

-----BEGIN CERTIFICATE-----
MIIDojCCAwugAwIBAgIJAIagm1uRqf6SMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
...
RBUkaTe/570sLHY0tvkIm5tEX36ESw==
-----END CERTIFICATE-----

If you have an expired cert and want to renew it, you can download a Certificate Signing Request (CSR). You then send the CSR to your CA to obtain a new cert. To generate a CSR for an alias, use the Generate a CSR for an alias API:

curl -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases/{alias_name}/csr"

The response should appear as:

-----BEGIN CERTIFICATE REQUEST-----
MIIB1DCCAT0CAQAwgZMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl
...
RF5RMytbkxkvPxIE17mDKJH0d8aekv/iEOItZ+BtQg+EibMUkkjTzQ==
-----END CERTIFICATE REQUEST-----

Delete a keystore/truststore or alias

You must use caution when deleting a keystore/truststore or alias. If you delete a keystore, truststore, or alias that is being used by a virtual host, target endpoint, or target server, all API calls through the virtual host or target endpoint/target server will fail.

Typically, the process you use to delete a keystore/truststore or alias is:

  1. Create a new keystore/truststore or alias as described above.
  2. For inbound connections, meaning an API request into Edge, update the virtual host configuration to reference the the new keystore and key alias.
  3. For outbound connections, meaning from Apigee to a backend server:
    1. Update the TargetEndpoint configuration for any API proxies that referenced the old keystore and key alias to reference the new keystore and key alias. If your TargetEndpoint references a TargetServer, update the TargetServer definition to reference the new keystore and key alias.
    2. If the keystore and truststore are referenced directly from the TargetEndpoint definition, then you must redeploy the proxy. If the TargetEndpoint references a TargetServer definition, and the TargetServer definition references the keystore and truststore, then no proxy redeployment is necessary.
    3. Confirm that your API proxies are functioning correctly.
    4. Delete the keystore/truststore or alias.

See Update the certificate in an alias for more.

Delete a keystore or truststore

You can delete a keystore or truststore by using the Delete a Keystore or Truststore API:

curl -u orgAdminEmail:password -X DELETE \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/myKeystoreName

If you delete and recreate a keystore or truststore that is being used by a virtual host, then you must redeploy your API proxies.

Delete an alias

You can delete an alias in a keystore or truststore by using the Delete alias API:

curl -u orgAdminEmail:password -X DELETE \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/myKeystoreName/aliases/{alias_name}