com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_link3' is unknown.

Auto Enrolling an Android Device

You can enroll your device automatically with WSO2 EMM via mutual SSL. For a better understanding of how auto-enrollment is achieved via mutual SSL, in WSO2 EMM, see Mutual SSL Authentication.

Configure WSO2 EMM for mutual SSL authentication

Prerequisite

Download and install OpenSSL. For more information, see how to  download and install OpenSSL.

Follow the steps given below to configure WSO2 EMM for mutual SSL authentication:

  1. Open the catalina-server.xml file that is in the <EMM_HOME>/repository/conf/tomcat directory and configure the clientAuth field that is under Connector protocol="org.apache.coyote.http11.Http11NioProtocol" as shown below:

    clientAuth="want"
    • The catalina-server.xml file has two connectors with the name Connector protocol="org.apache.coyote.http11.Http11NioProtocol". Make sure to configure the connector that has the property, scheme="https in it.
    • The values that can be assigned for clientAuth is true , want or false , where false is the default value that is assigned.
    • When you assign the value as want it indicates that mutual SSL is not a must for all the hosted web apps.There are many web apps in WSO2 EMM other than the web app the android agent communicates with. Therefore, it is not advisable to assign true as the value because it will then request the client certificate to be present for every request, including calls made from the UI.
  2. Configure the web.xml file that is in the <EMM_HOME>/repository/deployment/server/webapps/mdm-android-agent/WEB-INF directory by uncommenting the content given below:

    <!--Below configuration is used to redirect http requests to https-->
    <security-constraint>
       <web-resource-collection>
          <web-resource-name>MDM-Admin</web-resource-name>
          <url-pattern>/*</url-pattern>
       </web-resource-collection>
       <user-data-constraint>
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
       </user-data-constraint>
    </security-constraint>
     
    <!--For Mutual SSL enabling, please uncomment login-config and security-constraint tags-->
    <login-config>
       <auth-method>CLIENT-CERT</auth-method>
    </login-config>
    • If you have not started WSO2 EMM previously, you need to extract the content that is in the <EMM_HOME>/repository/deployment/server/webapps/api#device-mgt#android#v1.0.war file.
    • If you have started WSO2 EMM previously it means that the mdm-android-agent folder is already available in the <EMM_HOME>/repository/deployment/server/webapps directory.
  3. 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 = digitalSignature, keyEncipherment 
    
    [ 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 = digitalSignature, keyCertSign, cRLSign
  4. Generate a self-signed Certificate Authority (CA) certificate (version 3) and convert the certificate to the .pem format:

    If you have already configured iOS with the self-sign certificates, you can skip steps 3, 4 and 6 by and use the same certificates.

     

    1. Generate the private key.

      openssl genrsa -out <CA PRIVATE KEY> 4096

      Example:

      openssl genrsa -out ca_private.key 4096
    2. Generate a certificate signing request (CSR).

      openssl req -new -key <CA PRIVATE KEY> -out <CA CSR> 

      Example:

      openssl req -new -key ca_private.key -out ca.csr
    3. Self-sign the CSR by signing it with the private key.

      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> 

      Example:

      openssl x509 -req -days 365 -in ca.csr -signkey ca_private.key -out ca.crt -extensions v3_ca -extfile ./openssl.cnf
    4. Convert the private key to the .pem format.

      openssl rsa -in <CA PRIVATE KEY> -text > <CA PRIVATE PEM> 

      Example:

      openssl rsa -in ca_private.key -text > ca_private.pem
    5. Convert the CA certificate to the .pem format.

      openssl x509 -in <CA CRT> -out <CA CERT PEM>

      Example:

      openssl x509 -in ca.crt -out ca_cert.pem
  5. Generate the SSL certificate (version 3) based on your domain/IP address:
    1. Generate a private key.

      openssl genrsa -out <RSA_key>.key 4096 

      Example:

      openssl genrsa -out ia.key 4096
    2. Generate a certificate signing request (CSR).

      Provide the server IP/hostname as the common name when prompted

      openssl req -new -key <RSA_key>.key -out <CSR>.csr

      Example:

      openssl req -new -key ia.key -out ia.csr
    3. Sign the CSR with the CA private key to 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

      Example:

      openssl x509 -req -days 730 -in ia.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial 044324343 -out ia.crt
  6. Generate the client-side SSL certificate (version 3):
    1. Generate a private key.

      openssl genrsa -out <CLIENT_key>.key 4096 

      Example:

      openssl genrsa -out client.key 4096
    2. Generate a certificate signing request (CSR). When generating the client CSR, make sure to give the serial number of the device that is being enrolled as the common name.

      openssl req -new -key <CLIENT_key>.key -out <CSR>.csr

      Example:

      openssl req -new -key client.key -out client.csr
    3. Sign the CSR file with the CA private key to generate the client certificate.

      openssl x509 -req -days 730 -in <CSR>.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial <serial number> -out ia.crt

      Example:

      openssl x509 -req -days 730 -in client.csr -CA ca_cert.pem -CAkey ca_private.pem -set_serial 12438035315552875930 -out client.crt
    4. Convert the client certificate to the  .pem format for future use.

      openssl x509 -in <CLIENT CRT> -out <CLIENT CERT PEM>

      Example:

      openssl x509 -in client.crt -out client.pem
  7. Copy server side SSL certificate to the wso2carbon.jks file that is in the <EMM_HOME>/repository/resources/security directory using the command given below:

    openssl pkcs12 -export -out KEYSTORE.p12 -inkey ia.key -in ia.crt -CAfile ca_cert.pem -name "wso2carbon"
    keytool -importkeystore -srckeystore KEYSTORE.p12 -srcstoretype PKCS12 -destkeystore wso2carbon.jks 
  8. Copy the CA certificate details to the client-truststore.jks file that is in the <EMM_HOME>/repository/resources/security directory using the command given below:

    openssl pkcs12 -export -out ca.p12 -inkey ca_private.pem -in ca_cert.pem -name "cacert"
    keytool -importkeystore -srckeystore ca.p12 -srcstoretype PKCS12 -destkeystore client-truststore.jks

    Why is this step required?

    In the SSL handshake process, the server will send a set of trusted CA details to the client and request the client to send a certificate that matches the certificate signed by the server's trusted certificates.

  9. Restart the server and upload the generated certificate in step 6.d above, to the certificate section of the EMM console or add the certificate to the database via the REST API.

    For more information on adding the certificate to the database via the REST API, see Adding an SSL Certificate.

  10. Create a new BKS file having the name truststore and add the CA certificate.

    Ensure that you have the  bcprov-jdk16-146.jar file in the same folder where you will be generating the BKS file before you run this command.

    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'
  11. Create a new BKS file with the name keystore and add the client certificate generated bellow.
    Example:

    openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt -CAfile ca_cert.pem -name "wso2carbon"

    This client.p12 must be added to the keystore.bks file. For example as bellow,

    keytool -noprompt -importkeystore -v -srckeystore client.p12 -srcstoretype pkcs12 -alias wso2carbon -keystore keystore.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-146.jar -storepass 'wso2carbon'

  12. Copy the generated BKS files to the Android [IDP_Proxy]/res/raw folder. 
  13. Navigate to the Constants.java file of the IDP proxy module, which is under the org.wso2.emm.agent.proxy.utils package and configure the following fields.
    • Assign MUTUAL_SSL_AUTHENTICATOR as the value for AUTHENTICATOR_IN_USE.

      public static final String AUTHENTICATOR_IN_USE = MUTUAL_SSL_AUTHENTICATOR;
    • Assign MUTUAL_HTTP_CLIENT as the value for HTTP_CLIENT_IN_USE.

      public static final String HTTP_CLIENT_IN_USE = MUTUAL_HTTP_CLIENT;
    • Assign https as the value for SERVER_PROTOCOL.

      public static final String SERVER_PROTOCOL = "https://";
    • Optionally, if the passwords given when creating the BKS files was different from the default password used, which is wso2carbon, configure the TRUSTSTORE_PASSWORD and KEYSTORE_PASSWORD fields  with the password that were used and if the certificates are stored in the device storage, configure  TRUSTSTORE_LOCATIONKEYSTORE_LOCATION fields with the full path of the storage location.

      public static final String TRUSTSTORE_PASSWORD = "<PASSWORD>";
      public static final String KEYSTORE_PASSWORD = "<PASSWORD>";
      public static final String TRUSTSTORE_LOCATION = "<FULL_PATH_OF_THE_LOCATION>";
      public static final String KEYSTORE_LOCATION = "<FULL_PATH_OF_THE_LOCATION>";
  14. Navigate to the Constants.java file of the Android agent, which is under the org.wso2.emm.agent.utils package and configure the following fields.
    • When enrolling an Android device with WSO2 EMM, you have the ability to define if the device belongs to the COPE/BYOD device type. This is defined by the OWNERSHIP_BYOD and OWNERSHIP_COPE fields.
      Default configuration:

      public static final String OWNERSHIP_BYOD = "BYOD";
      public static final String OWNERSHIP_COPE = "COPE";

      When auto-enrolling an Android device, you must define the default device type of the registered device by assigning the respective value for the DEFAULT_OWNERSHIP field.

      Example: Define that the registered device belongs to the COPE device type by default.

      public static final String DEFAULT_OWNERSHIP = OWNERSHIP_COPE;
    • Optionally, if you wish to perform the enrollment in the background (without any interaction with the user) set the AUTO_ENROLLMENT_BACKGROUND_SERVICE_ENABLED field to true.

      This feature is applicable only for COPE devices where the organization has devices that are manufactured specifically for them (OEM scenarios). Further, the EMM agent MUST be pre-set by the OS as a Device Administrator. Once this is enabled, the Android agent will automatically trigger this service when the device is connected to the network for the first time.

      public static final boolean AUTO_ENROLLMENT_BACKGROUND_SERVICE_ENABLED = true;
    • Optionally, if you wish to skip initial step of the device registration where you need to enter the server address, you can pre-configure the server address details under the DEFAULT_HOST field.

       Click here to view the screen where you have to enter the server URL

      Make sure to provide the HTTPS details.

      public static final String DEFAULT_HOST = "https://<SERVER_IP>:<PORT>";

      Example:

      public static final String DEFAULT_HOST = "https://10.10.10.201:9443";


    • Optionally, configure the following fields to suit your requirement.
      • SKIP_LICENSE - Configure this field so that the end user license agreement is not shown to the user.
      • HIDE_LOGIN_UI -  Configure this fields to hide the login page, which is important for auto enrollment.
      • HIDE_UNREGISTER_BUTTON - Configure this field to hide the unregister button so that the user can not disenroll the device.
      • SKIP_WORK_PROFILE_CREATION - Configure this field, by assigning  the value as true to skip work-profile creation.

        For more information on the work profile that separates the personal and work data on Android devices, see Data Containerization for Android Device.

      • HIDE_ERROR_DIALOG - Configure this field to hide errors that pop up after the device is enrolled.
        Example : The user will not be notified of server configuration issues after the device is enrolled. 

      public static final boolean SKIP_LICENSE = true;
      public static final boolean HIDE_LOGIN_UI = true;
      public static final boolean HIDE_UNREGISTER_BUTTON = true;
      public static final boolean SKIP_WORK_PROFILE_CREATION = true;
      public static final boolean HIDE_ERROR_DIALOG = true;
  15. Compile the agent and install it on the device you wish to register.

    Before installing the agent make sure to check that the device serial number matches the embedded certificate's common name.

What's next

Once the above configurations are complete, you are able to register the device with WSO2 EMM by opening the installed EMM application on the device. Try out the steps given below:

  1. Tap the WSO2 agent application and open it.

  2. Tap ACTIVATE to enable the EMM device administrator on your device. A confirmation message will appear after enabling the device admin.

Now the Android device is successfully registered with WSO2 EMM.

com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_links2' is unknown.