The Android agent must have the CA certificate inside the application when configuring the Secure Sockets Layer (SSL). The CA certificate is stored in a BKS (bouncycastle) file. Follow the steps given below to create and generate a BKS file:
Prerequisites
Step 1: Creating a BKS file
Navigate to the openssl.cnf
file of the OpenSSL installation.
Make a copy of the openssl.cnf
file, move it to another location, and configure the file to generate version 3 certificates as shown below:
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints=CA:TRUE
keyUsage = Digital Signature, Key Encipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
basicConstraints = critical,CA:true
# So we do this instead.
#basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
keyUsage = Digital Signature, Certificate Sign, CRL Sign
In the location where you modified and saved the openssl.cnf
file, run the following commands to generate a self-signed Certificate Authority (CA) certificate (version 3) and convert the certificate to the .pem
format:
openssl genrsa -out <CA PRIVATE KEY> 4096
For example: openssl genrsa -out ca_private.key 4096
openssl req -new -key <CA PRIVATE KEY> -out <CA CSR>
For example: openssl req -new -key ca_private.key -out ca.csr
openssl x509 -req -days <DAYS> -in <CA CSR> -signkey <CA PRIVATE KEY> -out <CA CRT> -extensions v3_ca -extfile <PATH-TO-MODIFIED-openssl.cnf-FILE>
For example: openssl x509 -req -days 365 -in ca.csr -signkey ca_private.key -out ca.crt -extensions v3_ca -extfile ./openssl.cnf
openssl rsa -in <CA PRIVATE KEY> -text > <CA PRIVATE PEM>
For example: openssl rsa -in ca_private.key -text > ca_private.pem
openssl x509 -in <CA CRT> -out <CA CERT PEM>
For example: openssl x509 -in ca.crt -out ca_cert.pem
In the same location, run the following commands to generate a Registration Authority (RA) certificate (version 3), sign it with the CA, and convert the certificate to the .pem
format.
openssl genrsa -out <RA PRIVATE KEY> 4096
For example: openssl genrsa -out ra_private.key 4096
openssl req -new -key <RA PRIVATE KEY> -out <RA CSR>
For example: openssl req -new -key ra_private.key -out ra.csr
openssl x509 -req -days <DAYS> -in <RA CSR> -CA <CA CRT> -CAkey <CA PRIVATE KEY> -set_serial <SERIAL NO> -out <RA CRT> -extensions v3_req -extfile <PATH-TO-MODIFIED-
openssl.cnf-FILE
>
For example: openssl x509 -req -days 365 -in ra.csr -CA ca.crt -CAkey ca_private.key -set_serial 02 -out ra.crt -extensions v3_req -extfile ./openssl.cnf
openssl rsa -in <CA PRIVATE KEY> -text > <RA PRIVATE PEM>
For example: openssl rsa -in ra_private.key -text > ra_private.pem
openssl x509 -in <RA CRT> -out <RA CERT PEM>
For example: openssl x509 -in ra.crt -out ra_cert.pem
Generate the SSL certificate (version 3) based on your domain/IP address:
- Generate an RSA key.
openssl genrsa -out <RSA_key>.key 4096
For example:
openssl genrsa -out ia.key 4096
- Generate a CSR file.
openssl req -new -key <RSA_key>.key -out <CSR>.csr
For example:
openssl req -new -key ia.key -out ia.csr
Enter your server IP address/domain name (e.g., 192.168.1.157) as the Common Name else provisioning will fail. - Generate the SSL certificate.
openssl x509 -req -days 730 -in <CSR>.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial <serial number> -out ia.crt
For example:
openssl x509 -req -days 730 -in ia.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial 044324343 -out ia.crt
Export the SSL, CA, and RA files as PKCS12 files with an alias.
Export the SSL file as a PKCS12 file with "wso2carbo
n" as the alias.
openssl pkcs12 -export -out <KEYSTORE>.p12 -inkey <RSA_key>.key -in ia.crt -CAfile ca_cert.pem -name "<alias>"
For example:
openssl pkcs12 -export -out KEYSTORE.p12 -inkey ia.key -in ia.crt -CAfile ca_cert.pem -name "wso2carbon"
- Export the CA file as a PKCS12 file with an alias.
openssl pkcs12 -export -out <CA>.p12 -inkey <CA private key>.pem -in <CA Cert>.pem -name "<alias>"
For example:
openssl pkcs12 -export -out ca.p12 -inkey ca_private.pem -in ca_cert.pem -name "cacert"
In the above example, cacert
has been used as the CA alias. - Export the RA file as a PKCS12 file with an alias.
openssl pkcs12 -export -out <RA>.p12 -inkey <RA private key>.pem -in <RA Cert>.pem -chain -CAfile <CA cert>.pem -name "<alias>"
For example:
openssl pkcs12 -export -out ra.p12 -inkey ra_private.pem -in ra_cert.pem -chain -CAfile ca_cert.pem -name "racert"
In the above example, racert
has been used as the RA alias.
- Copy the three P12 files to the
<EMM_HOME>/repository/resources/security
directory. - Import the generated P12 files as follows:
Import the generated <KEYSTORE>.p12
file into the wso2carbon.jks
and client-truststore.jks
in the <EMM_HOME>/repository/resources/security
directory.
keytool -importkeystore -srckeystore <KEYSTORE>.p12 -srcstoretype PKCS12 -destkeystore <wso2carbon.jks/client-truststore.jks>
For example:
keytool -importkeystore -srckeystore KEYSTORE.p12 -srcstoretype PKCS12 -destkeystore wso2carbon.jks
keytool -importkeystore -srckeystore KEYSTORE.p12 -srcstoretype PKCS12 -destkeystore client-truststore.jks
Import the generated <CA>.p12
and <RA>.p12
files into the wso2certs.jks
file, which is in the <EMM_HOME>/repository/resources/security
directory.
keytool -importkeystore -srckeystore <CA/RA>.p12 -srcstoretype PKCS12 -destkeystore wso2emm.jks
For example:
keytool -importkeystore -srckeystore ca.p12 -srcstoretype PKCS12 -destkeystore wso2certs.jks
Enter the keystore password as wso2carbon
and keystore key password as cacert
.
keytool -importkeystore -srckeystore ra.p12 -srcstoretype PKCS12 -destkeystore wso2certs.jks
Enter the keystore password as wso2carbon
and keystore key password as racert
.
Step 2: Generating a BKS file
Generate the BKS file:
keytool -noprompt -import -v -trustcacerts -alias 'openssl x509 -inform PEM -subject_hash -noout -in ca_cert.pem' -file ca_cert.pem -keystore emm_truststore.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-146.jar -storepass 'wso2carbon'
If you are using an SSL certificate by a trusted authority such as GoDaddy, the cert.crt
defined in the command should be the interim certificate.
Example:
keytool -noprompt -import -v -trustcacerts -alias godaddy -file cert.crt -keystore emm_truststore.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-146.jar -storepass 'wso2carbon'
Optionally, view the list of certificates in the BKS form using the following command:
keytool -list -v -keystore "emm_truststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-1.46.jar" -storetype BKS -storepass "wso2carbon"
- Copy the generated
emm_truststore.bks
file to the Android res/raw
folder. - Navigate to the
Constants.java
file, which is in the Android folder and configure the following:- Provide the
HTTPS_HOST_IP
as the value for the SERVER_PORT
parameter.
Example: 9443
. - Change the
SERVER_PROTOCOL
to https://
. - Provide the BKS file password as the value for the
TRUSTSTORE_PASSWORD
parameter.
public static boolean DEBUG_MODE_ENABLED = false;
public static boolean LOCAL_NOTIFICATIONS_ENABLED = true;
public static boolean GCM_ENABLED = false;
public static String SERVER_IP = "";
public static String SERVER_PORT = "9443";
public static String SERVER_PROTOCOL = "https://";
public static String API_VERSION = "1.0.0";
public static String SERVER_APP_ENDPOINT = "/EMM/api/";
public static String OAUTH_ENDPOINT = "/oauth2/token";
public static String SENDER_ID_ENDPOINT = "devices/sender_id/";
public static String IS_REGISTERED_ENDPOINT = "devices/isregistered/";
public static String LICENSE_ENDPOINT = "devices/license/";
public static String REGISTER_ENDPOINT = "devices/register/";
public static String UNREGISTER_ENDPOINT = "devices/unregister/";
public static String NOTIFICATION_ENDPOINT = "notifications/pendingOperations/";
public static String SERVER_URL = SERVER_PROTOCOL + SERVER_IP + ":"
+ SERVER_PORT + SERVER_APP_ENDPOINT;
public static final String TRUSTSTORE_PASSWORD = "";
public static final String EULA_TITLE = "POLICY AGREEMENT";