Fix Unit tests.
authorAndrii Androsov <a.androsov@samsung.com>
Wed, 28 Sep 2016 11:51:07 +0000 (14:51 +0300)
committerJee Hyeok Kim <jihyeok13.kim@samsung.com>
Fri, 30 Sep 2016 08:28:30 +0000 (08:28 +0000)
1) Add cleaning up for CERTIFICATE_TABLE and CRL_TABLE in Mongo.
2) Fix random test execution with help of @BeforeClass annotation in CrlResourceTest.
3) Fix SVACE issues.
4) Add new java documentation for public and private methods.

Change-Id: I43b7c2dc814d67d3a53b598f4eddf3c1acc2a94d
Signed-off-by: Andrii Androsov <a.androsov@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/12177
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: dongik Lee <dongik.lee@samsung.com>
Reviewed-by: Jee Hyeok Kim <jihyeok13.kim@samsung.com>
14 files changed:
cloud/account/README
cloud/account/properties/config.properties
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateConstants.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/cert/CertificateStorage.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/crl/CrlManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/credprov/crl/CrlResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/cert/CSRParser.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/cert/CertificateBuilder.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/cert/CertificateExtension.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/x509/crl/CrlIssuer.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/credprov/cert/CertificateResourceTest.java
cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/account/credprov/crl/CrlResourceTest.java

index 85353ef..c5cd318 100644 (file)
@@ -33,6 +33,6 @@ Build and Run
        - Before you run a Accout server, You need to set up following steps.
           1) Install MongoDB
           2) Install Github certificates for github.com and *.github.com.
-6) Please download: file from http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html: Java Cryptography Extension
-         1.Extract files from zip.
-         2.Place local_policy.jar and US_export_policy.jar files in/usr/lib/jvm/PATH_TO_JDK/jre/lib/security
+5) Please download: file from http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html: Java Cryptography Extension
+         1.Extract files from zip. 
+         2.Place local_policy.jar and US_export_policy.jar files in/usr/lib/jvm/PATH_TO_JDK/jre/lib/security 
index 73d9aaa..9e82e75 100644 (file)
@@ -1,17 +1,18 @@
 #New Serial number
-#Wed Sep 07 17:08:34 EEST 2016
+#Tue Sep 27 16:11:46 EEST 2016
 keyGeneratorAlgorithm=ECDSA
 notAfterInterval=20
 securityProvider=BC
 ellipticCurve=secp256r1
+keystoreDir=keystore
 keyStoreLocation=keystore{0}certificateStorage.jks
+keystoreType=BKS
 nextUpdateInterval=1
 signatureAlgorithm=SHA256withECDSA
-keystoreType=BKS
 rootOU=OCF Sub CA
-serialNumber=515
+serialNumber=0
 rootO=Samsung
-caAlias=uuid\:31313131-3131-3131-3131-313131313131
 subjectName=uuid\:31313131-3131-3131-3131-313131313131
+caAlias=uuid\:31313131-3131-3131-3131-313131313131
 password=PASSWORD
 rootC=KR
index 68d6fb3..4ba157a 100644 (file)
@@ -45,46 +45,96 @@ import static java.security.cert.CertificateFactory.getInstance;
  */
 public final class CertificateConstants {
 
+    /**
+     * Properties object is used for loading pre-defined configurations: algorithm names and so on.
+     */
     public static final Properties PROPERTIES = new Properties();
 
     /**
      * Load properties from specified properties file.
      */
     static {
-        try {
-            PROPERTIES.load(new FileInputStream(Constants.PROPERTIES_FILE_NAME));
+        try (FileInputStream inputStream = new FileInputStream(Constants.PROPERTIES_FILE_NAME)) {
+            PROPERTIES.load(inputStream);
         } catch (IOException e) {
             Log.e(e.getMessage());
         }
     }
 
+    /**
+     * Base 64 encoding constant for comparing request encoding.
+     */
     public static final String BASE_64 = "oic.sec.encoding.base64";
 
+    /**
+     * Der encoding constant for comparing request encoding.
+     */
     public static final String DER = "oic.sec.encoding.der";
 
+    /**
+     * Name of security provider, load from properties.
+     */
     public static final String SECURITY_PROVIDER = PROPERTIES.getProperty("securityProvider");
 
+    /**
+     * Not after interval for X509Certificate generation, load from properties.
+     */
     public static final String NOT_AFTER_INTERVAL = PROPERTIES.getProperty("notAfterInterval");
 
+    /**
+     * Next Update interval. is used for generation X509CRL, load from properties.
+     */
     public static final String NEXT_UPDATE_INTERVAL = PROPERTIES.getProperty("nextUpdateInterval");
 
+    /**
+     * Signature algorithm, is used for signing certificates and CRLs, load from properties.
+     */
     public static final String SIGNATURE_ALGORITHM = PROPERTIES.getProperty("signatureAlgorithm");
 
+    /**
+     * KeyStore type, is used for private key storage and for root certificate storage
+     */
     static final String KEYSTORE_TYPE = PROPERTIES.getProperty("keystoreType");
 
+    /**
+     * CA Alias name, is used for storing ca certificate to key storage.
+     */
     static final String CA_ALIAS = PROPERTIES.getProperty("caAlias");
 
+    /**
+     * Curve name, is used in signing algorithm for X509 certificate generation.
+     */
     static final String CURVE = PROPERTIES.getProperty("ellipticCurve");
 
+    /**
+     * Key generation algorithm is used for generation private and public keys.
+     */
     static final String KEY_GENERATOR_ALGORITHM = PROPERTIES.getProperty("keyGeneratorAlgorithm");
 
+    /**
+     * Date format, is used to parse date with UTC TIME format for certificate and CRL generation.
+     */
     public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
 
+    /**
+     * String constant is used to create keystore directory.
+     */
+    public static final String KEYSTORE_DIR = PROPERTIES.getProperty("keystoreDir");
+
+    /**
+     * X500Name for ca issuer, is used for issuing personal certificates and CRLs.
+     */
     public static final X500Name CA_ISSUER = Utility.getName(PROPERTIES.getProperty("subjectName"),
             PROPERTIES.getProperty("rootC"), PROPERTIES.getProperty("rootO"), PROPERTIES.getProperty("rootOU"));
 
+    /**
+     * Shared AccountDBManager to get rid of repeatable links on the same object.
+     */
     public static final AccountDBManager ACCOUNT_DB_MANAGER = AccountDBManager.getInstance();
 
+    /**
+     * Certificate factory is used during certificate generation process.
+     */
     public static CertificateFactory CERTIFICATE_FACTORY;
 
     static {
@@ -96,25 +146,29 @@ public final class CertificateConstants {
     }
 
     /**
-     * Path to keystore file
+     * Path to keystore file, retrieved from properties file.
      */
     public static final File KEYSTORE_FILE = new File(MessageFormat.
             format(PROPERTIES.getProperty("keyStoreLocation"), File.separator));
 
     /**
      * Set specified value for specified property.
+     *
      * @param property specified property
-     * @param value specified property value.
+     * @param value    specified property value.
      */
     public static void set(String property, String value) {
         PROPERTIES.setProperty(property, value);
-        try {
-            PROPERTIES.store(new FileOutputStream(Constants.PROPERTIES_FILE_NAME), "New Serial number");
+        try (FileOutputStream outputStream = new FileOutputStream(Constants.PROPERTIES_FILE_NAME)) {
+            PROPERTIES.store(outputStream, "New Serial number");
         } catch (IOException e) {
             Log.e(e.getMessage());
         }
     }
 
+    /**
+     * Private constructor makes class non-instantiable utility class.
+     */
     private CertificateConstants() {
         throw new AssertionError();
     }
index bb36946..8bb7d53 100644 (file)
@@ -31,17 +31,15 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static org.iotivity.cloud.accountserver.Constants.CERTIFICATE_TABLE;
-import static org.iotivity.cloud.accountserver.Constants.KEYFIELD_DID;
-import static org.iotivity.cloud.accountserver.Constants.KEYFIELD_REVOKED;
+import static org.iotivity.cloud.accountserver.Constants.*;
 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.ACCOUNT_DB_MANAGER;
 
 
 /**
  * This class is used as DB manager for CertificateTable.
  * With help of this class we can save certificate info to DB,
- * retrieve it from DB by specified in constructor device id,
- * updateX509CRL certificate, also it helps us get user Id from Token
+ * retrieve it from DB by specified device id,
+ * update X509 certificate, also it helps us to get user Id from Token
  * Table by specified device id.
  */
 final class CertificateManager {
@@ -63,7 +61,9 @@ final class CertificateManager {
     private final String deviceId;
 
     /**
-     * Constructs certificateMananger with specified device id.
+     * Constructs certificateMananger with specified device id. Initialize payload
+     * as new hash map instance.
+     *
      * @param deviceId specified device identifier for this CertificateManager.
      */
     CertificateManager(String deviceId) {
@@ -79,33 +79,34 @@ final class CertificateManager {
     }
 
     /**
-     * Puts for specified key, specified value to
-     * object payload;
-     * @param key specified key value
-     * @param value specified value
+     * Puts specified value for specified key to payload;
+     *
+     * @param key   specified String key value
+     * @param value specified Object value
      */
     public void put(String key, Object value) {
         payLoad.put(key, value);
     }
 
     /**
-     * Saves new certificate to DB with specified columns.
+     * Saves certificate information: serial number, not after, to DB with specified columns.
      *
      * @param serialNumber specified certificate serial number
-     * @param notAfter validation date not after
-     * @param notBefore validation date not before
+     * @param notAfter     validation date not after
+     * @param notBefore    validation date not before
      */
     void save(BigInteger serialNumber, Date notAfter, Date notBefore) {
         ACCOUNT_DB_MANAGER.insertRecord(CERTIFICATE_TABLE,
                 CERTIFICATE_TABLE_TYPE_CASTING_MANAGER.convertObjectToMap(
                         new CertificateTable(serialNumber.toString(), notAfter,
-                        notBefore, deviceId, Utility.getUserID(deviceId), false)));
+                                notBefore, deviceId, Utility.getUserID(deviceId), false)));
     }
 
     /**
-     * Updates certificate table with specified revoked column.
+     * Updates certificate table by revoked column.
+     *
      * @param certificateTable certificate to be updated.
-     * @param revoked specified value for revoke
+     * @param revoked          specified value for revoke
      */
     void update(CertificateTable certificateTable, boolean revoked) {
         certificateTable.setRevoked(revoked);
@@ -114,8 +115,8 @@ final class CertificateManager {
     }
 
     /**
-     * Returns certificate from database, according to specified
-     * device id
+     * Returns certificate from database for specified in constructor
+     * device id.
      */
     public CertificateTable getCertificate() {
         HashMap<String, Object> condition = new HashMap<>();
@@ -123,7 +124,7 @@ final class CertificateManager {
         condition.put(KEYFIELD_REVOKED, false);
         List<HashMap<String, Object>> listMap = ACCOUNT_DB_MANAGER.selectRecord(
                 CERTIFICATE_TABLE, condition);
-        if (!listMap.isEmpty()) {
+        if (listMap != null && !listMap.isEmpty()) {
             return CERTIFICATE_TABLE_TYPE_CASTING_MANAGER
                     .convertMaptoObject(
                             listMap.get(0),
@@ -132,4 +133,4 @@ final class CertificateManager {
             return null;
         }
     }
-}
+}
\ No newline at end of file
index e7113d5..13bf1d5 100644 (file)
@@ -49,6 +49,7 @@ import org.iotivity.cloud.util.Log;
 
 import java.io.IOException;
 import java.security.GeneralSecurityException;
+import java.security.PublicKey;
 import java.security.Security;
 import java.security.cert.CRLException;
 import java.security.cert.X509Certificate;
@@ -77,15 +78,8 @@ public class CertificateResource extends Resource {
     private static final Cbor<Map<String, Object>> MAP_CBOR = new Cbor<>();
 
     /**
-     * Constructs certificate resourcewith specified prefixes
-     */
-    public CertificateResource() {
-        super(Arrays.asList(PREFIX_OIC, CREDPROV_URI, CERT_URI));
-    }
-
-    /**
-     * Insert BouncyCastleProvider into 0 position in security provider list.
-     * Init KeyStore, Generate CA certificate and save it to keyStore.
+     * Inserts BouncyCastleProvider into 0 position in security provider list,
+     * inits KeyStore, generates CA certificate and saves it to keyStore.
      */
     static {
         Security.insertProviderAt(new BouncyCastleProvider(), 0);
@@ -100,6 +94,13 @@ public class CertificateResource extends Resource {
         }
     }
 
+    /**
+     * Constructs certificate resource with specified prefixes.
+     */
+    public CertificateResource() {
+        super(Arrays.asList(PREFIX_OIC, CREDPROV_URI, CERT_URI));
+    }
+
     @Override
     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
             throws ServerException {
@@ -115,70 +116,106 @@ public class CertificateResource extends Resource {
     }
 
     /**
-     * Handles post requests to this resource
+     * Handles post requests to Certificate Resource.
+     * Request should be with specified format
+     * POST /oic/credprov/cert
+     * {
+     *      “di” : “11-22-xx”,
+     *      “csr” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded CSR Binary>”
+     *      }
+     * }
+     * Method checks encoding, and decodes data by specified encoding if needed.
+     *
+     * Method issus a certificate including User UUID in extension field,
+     * stores issuing information (serial number, validity, device uuid, user uuid) for management (e.g. re-issue).
+     * Response should be in next format for example:
+     * 2.04 CHANGED
+     * {
+     *      “di” : “1111-22-xx”,
+     *      “cert” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded Cert. Binary>”
+     *       },
+     *      “certchain” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded CA Cert. chain>”
+     *       }
+     * }
+     * or returns BAD_REQUEST: 4.0.1 if any exceptions occured.
+     *
      * @param request request with payload information.
      * @throws ServerException
      */
     private IResponse handlePostRequest(IRequest request)
             throws ServerException {
-        Map<String, Object> payloadData = MAP_CBOR
-                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+        byte[] requestPayload = request.getPayload();
         IResponse response = MessageBuilder.createResponse(request, ResponseStatus.BAD_REQUEST);
-        Object csr = payloadData.get(Constants.REQ_CSR);
-        if (csr != null && csr instanceof Map) {
-            Object encoding =((Map<String, Object>)csr).get(ENCODING);
-            Object data = ((Map<String, Object>)csr).get(DATA);
-            if (encoding != null && encoding instanceof String && data != null && data instanceof byte[]) {
-                byte[] csrData = (byte[]) data;
-                if (encoding.equals(BASE_64)) {
-                    csrData = Base64.decode(csrData);
-                }
-                try {
-                    CSRParser parser = new CSRParser(csrData);
-                    String commonName = parser.getCommonName();
-                    String pattern = "^uuid:(.*)$";
-                    Pattern r = Pattern.compile(pattern);
-                    Matcher m = r.matcher(commonName);
-                    String deviceId = (String) payloadData.get(RESP_DEVICE_ID);
-                    if (m.find() && m.group(1).equals(deviceId) && parser.isSignatureValid()) {
-                        CertificateManager certificateManager = new CertificateManager(deviceId);
-                        CertificateTable certificateTable = certificateManager.getCertificate();
-                        if (certificateTable != null) {
-                            try {
-                                CrlManager.CRL_MANAGER.revoke(certificateTable.getSerialNumber());
-                            } catch (CRLException | OperatorCreationException e) {
-                                Log.e(e.getMessage() + e.getClass());
-                            }
-                            certificateManager.update(certificateTable, true);
+        if (requestPayload != null) {
+            Map<String, Object> payloadData = MAP_CBOR
+                    .parsePayloadFromCbor(requestPayload, HashMap.class);
+            if (payloadData != null) {
+                Object csr = payloadData.get(Constants.REQ_CSR);
+                if (csr != null && csr instanceof Map) {
+                    Object encoding = ((Map<String, Object>) csr).get(ENCODING);
+                    Object data = ((Map<String, Object>) csr).get(DATA);
+                    if (encoding != null && encoding instanceof String && data != null && data instanceof byte[]) {
+                        byte[] csrData = (byte[]) data;
+                        if (encoding.equals(BASE_64)) {
+                            csrData = Base64.decode(csrData);
                         }
-                        CertificateExtension extension = new CertificateExtension(Extension.subjectAlternativeName,
-                                false, new DERSequence(new ASN1Encodable[]
-                                {new GeneralName(GeneralName.dNSName, Constants.KEYFIELD_USERID + ":" +
-                                        Utility.getUserID(deviceId))}));
-                        CertificateBuilder certBuilder = new CertificateBuilder(parser.getSubject(),
-                                parser.getPublicKey(), extension );
                         try {
-                            X509Certificate personal = certBuilder.build();
-                            byte[] encodedCert = personal.getEncoded();
-                            byte[] encodedCa = CertificateStorage.ROOT_CERTIFICATE.getEncoded();
-                            if (encoding.equals(CertificateConstants.BASE_64)) {
-                                encodedCert = Base64.encode(encodedCert);
-                                encodedCa =  Base64.encode(encodedCa);
+                            CSRParser parser = new CSRParser(csrData);
+                            String commonName = parser.getCommonName();
+                            String pattern = "^uuid:(.*)$";
+                            Pattern r = Pattern.compile(pattern);
+                            Matcher m = r.matcher(commonName);
+                            String deviceId = (String) payloadData.get(RESP_DEVICE_ID);
+                            if (m.find() && m.group(1).equals(deviceId) && parser.isSignatureValid()) {
+                                CertificateManager certificateManager = new CertificateManager(deviceId);
+                                CertificateTable certificateTable = certificateManager.getCertificate();
+                                if (certificateTable != null) {
+                                    try {
+                                        CrlManager.CRL_MANAGER.revoke(certificateTable.getSerialNumber());
+                                    } catch (CRLException | OperatorCreationException e) {
+                                        Log.e(e.getMessage() + e.getClass());
+                                    }
+                                    certificateManager.update(certificateTable, true);
+                                }
+                                PublicKey publicKey = parser.getPublicKey();
+                                if (publicKey != null) {
+                                    CertificateExtension extension = new CertificateExtension(Extension.subjectAlternativeName,
+                                            false, new DERSequence(new ASN1Encodable[]
+                                            {new GeneralName(GeneralName.dNSName, Constants.KEYFIELD_USERID + ":" +
+                                                    Utility.getUserID(deviceId))}));
+                                    CertificateBuilder certBuilder = new CertificateBuilder(parser.getSubject(),
+                                            publicKey, extension);
+                                    try {
+                                        X509Certificate personal = certBuilder.build();
+                                        byte[] encodedCert = personal.getEncoded();
+                                        byte[] encodedCa = CertificateStorage.ROOT_CERTIFICATE.getEncoded();
+                                        if (encoding.equals(CertificateConstants.BASE_64)) {
+                                            encodedCert = Base64.encode(encodedCert);
+                                            encodedCa = Base64.encode(encodedCa);
+                                        }
+                                        certificateManager.put(Constants.RESP_DEVICE_ID, deviceId);
+                                        certificateManager.put(Constants.CERT, new CSR(encoding.toString(), encodedCert));
+                                        certificateManager.put(Constants.CERT_CHAIN, new CSR(encoding.toString(), encodedCa));
+                                        certificateManager.save(personal.getSerialNumber(), personal.getNotAfter(),
+                                                personal.getNotBefore());
+                                        response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
+                                                ContentFormat.APPLICATION_CBOR,
+                                                MAP_CBOR.encodingPayloadToCbor(certificateManager.getPayLoad()));
+                                    } catch (GeneralSecurityException | OperatorCreationException | CertIOException e) {
+                                        Log.e(e.getMessage());
+                                    }
+                                }
                             }
-                            certificateManager.put(Constants.RESP_DEVICE_ID, deviceId);
-                            certificateManager.put(Constants.CERT, new CSR(encoding.toString(), encodedCert));
-                            certificateManager.put(Constants.CERT_CHAIN,  new CSR(encoding.toString(), encodedCa));
-                            certificateManager.save(personal.getSerialNumber(), personal.getNotBefore(),
-                                    personal.getNotAfter());
-                            response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
-                                    ContentFormat.APPLICATION_CBOR,
-                                    MAP_CBOR.encodingPayloadToCbor(certificateManager.getPayLoad()));
-                        } catch (GeneralSecurityException | OperatorCreationException | CertIOException e) {
+                        } catch (IOException e) {
                             Log.e(e.getMessage());
                         }
                     }
-                } catch (IOException e) {
-                    Log.e(e.getMessage());
                 }
             }
         }
@@ -186,7 +223,7 @@ public class CertificateResource extends Resource {
     }
 
     /**
-     * This class is used for response
+     * Response utility class.
      */
     private static final class CSR {
 
@@ -199,10 +236,16 @@ public class CertificateResource extends Resource {
             this.data = data;
         }
 
+        /**
+         * Return encoding.
+         */
         public String getEncoding() {
             return encoding;
         }
 
+        /**
+         * Retrieves data.
+         */
         public byte[] getData() {
             return data;
         }
index f632a20..9363549 100644 (file)
@@ -23,12 +23,11 @@ package org.iotivity.cloud.accountserver.resources.credprov.cert;
 
 import org.bouncycastle.asn1.x509.BasicConstraints;
 import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.cert.CertIOException;
 import org.bouncycastle.jce.ECNamedCurveTable;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.operator.OperatorCreationException;
 import org.iotivity.cloud.accountserver.x509.cert.CertificateBuilder;
 import org.iotivity.cloud.accountserver.x509.cert.CertificateExtension;
+import org.iotivity.cloud.util.Log;
 
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -42,6 +41,10 @@ import java.security.cert.X509Certificate;
 
 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
 
+/**
+ * This class is used for loading and storing key store.
+ * Also it generates CA certificate and puts it to keystore.
+ */
 public final class CertificateStorage {
 
     /**
@@ -51,78 +54,62 @@ public final class CertificateStorage {
     private static final String PASSWORD = PROPERTIES.getProperty("password");
 
     /**
-     * Keystore object for save, get data from keystore.
+     * Root private key is used for signing certificates ans CRLs.
      */
-    private static KeyStore keyStore;
-
     public static PrivateKey ROOT_PRIVATE_KEY;
 
-    public static X509Certificate ROOT_CERTIFICATE;
-
-    private CertificateStorage() {
-        throw new AssertionError();
-    }
-
     /**
-     * Init KeyStore. If it does not exists, create it and push to KEYSTORE_FILE.
+     * Root certificate, is used for isssuing low level certificates.
      */
-    static void init() throws GeneralSecurityException, IOException, OperatorCreationException {
-        Files.createDirectories(Paths.get("keystore"));
-        keyStore = load(null, null);
-        store();
-        CertificateStorage.generateCACertificate();
-        CertificateStorage.saveCertificatePrivateKey();
-    }
+    public static X509Certificate ROOT_CERTIFICATE;
 
     /**
-     * Load KeyStore with default keystore file and password.
-     *
-     * @return KeyStore instance.
+     * Keystore object to save, retrieve ca private key and ca certificate from keystore.
      */
-    public static void load() throws GeneralSecurityException, IOException {
-        keyStore = load(new FileInputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
-        initRoot();
-    }
+    private static KeyStore keyStore;
 
     /**
-     * Loads KeyStore with defined inputStream object and password.
-     *
-     * @param is       specified inputStream which contains keystore bytes.
-     * @param password specified password for opening keystore.
-     * @return KeyStore instance.
+     * Private contructor to make this class non-instantiable.
      */
-    private static KeyStore load(InputStream is, char[] password) throws IOException, GeneralSecurityException {
-        KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE, BouncyCastleProvider.PROVIDER_NAME);
-        keyStore.load(is, password);
-        return keyStore;
+    private CertificateStorage() {
+        throw new AssertionError();
     }
 
-
     /**
-     * Stores keyStore to default file KEYSTORE_FILE with default password.
+     * Loads keystore with null paramaters.
+     * Stores it empty version. Generates CA certificate and private key and
+     * saves it to key storage.
      */
-    static void store() throws IOException, GeneralSecurityException {
-        store(keyStore, new FileOutputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
+    static void init() throws GeneralSecurityException, IOException, OperatorCreationException {
+        Files.createDirectories(Paths.get(KEYSTORE_DIR));
+        keyStore = KeyStore.getInstance(KEYSTORE_TYPE, SECURITY_PROVIDER);
+        keyStore.load(null, null);
+        generate();
     }
 
     /**
-     * Stores KeyStore to file outputstream with specifie password.
+     * Loads KeyStore intance from created keystore file and with default password.
      *
-     * @param keyStore
+     * @return KeyStore instance.
      */
-    private static void store(KeyStore keyStore, FileOutputStream out, char[] password) throws GeneralSecurityException,
-            IOException {
-        keyStore.store(out, password);
-        out.close();
+    static void load() throws GeneralSecurityException, IOException {
+        keyStore = KeyStore.getInstance(KEYSTORE_TYPE, SECURITY_PROVIDER);
+        try (InputStream inputStream = new FileInputStream(KEYSTORE_FILE)) {
+            keyStore.load(inputStream, PASSWORD.toCharArray());
+        } catch (IOException ioException) {
+            Log.e(ioException.getMessage());
+        }
+        ROOT_PRIVATE_KEY = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
+        ROOT_CERTIFICATE = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
     }
 
     /**
-     * Generates X509Certificate  with PublicKey and PrivateKey
+     * Generates CA X509Certificate and private key and stores it to key storage.
      *
      * @return certificate and private key
      */
-    private static void generateCACertificate() throws GeneralSecurityException,
-            OperatorCreationException, CertIOException {
+    private static void generate() throws GeneralSecurityException,
+            OperatorCreationException, IOException {
         if (ROOT_PRIVATE_KEY == null) {
             KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, SECURITY_PROVIDER);
             g.initialize(ECNamedCurveTable.getParameterSpec(CURVE), new SecureRandom());
@@ -131,21 +118,21 @@ public final class CertificateStorage {
             ROOT_CERTIFICATE = new CertificateBuilder(CA_ISSUER, pair.getPublic(),
                     new CertificateExtension(Extension.basicConstraints, false,
                             new BasicConstraints(true))).build();
+            keyStore.setCertificateEntry(CA_ALIAS, ROOT_CERTIFICATE);
+            keyStore.setKeyEntry(CA_ALIAS, ROOT_PRIVATE_KEY, PASSWORD.toCharArray(),
+                    new Certificate[]{ROOT_CERTIFICATE});
+            store();
         }
     }
 
     /**
-     * Stores certificate and private key to keystore.
+     * Stores keyStore instance to default keystore file with default password.
      */
-    private static void saveCertificatePrivateKey() throws GeneralSecurityException, IOException {
-        keyStore.setCertificateEntry(CA_ALIAS, ROOT_CERTIFICATE);
-        keyStore.setKeyEntry(CA_ALIAS, ROOT_PRIVATE_KEY, PASSWORD.toCharArray(),
-                new Certificate[]{ROOT_CERTIFICATE});
-        store();
-    }
-
-    private static void initRoot() throws GeneralSecurityException {
-        ROOT_PRIVATE_KEY = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
-        ROOT_CERTIFICATE = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
+    private static void store() throws IOException, GeneralSecurityException {
+        try (FileOutputStream out = new FileOutputStream(KEYSTORE_FILE)) {
+            keyStore.store(out, PASSWORD.toCharArray());
+        } catch (IOException ioException) {
+            Log.e(ioException.getMessage());
+        }
     }
 }
index d6d0f6a..ca61263 100644 (file)
@@ -40,55 +40,80 @@ import static org.iotivity.cloud.accountserver.resources.credprov.cert.Certifica
 import static org.iotivity.cloud.accountserver.x509.crl.CrlIssuer.CRL_ISSUER;
 
 /**
- * Class is used for managing CRLs(creation, revoke, update)
+ * Class is used to manage CRLs. It helps to create,
+ * update CRLS, revoke certificates.
  */
 public final class CrlManager {
 
     /**
-     * Static manager for CRLs.
-     */
-    public static CrlManager CRL_MANAGER;
-    /**
      * Casting manager for working with CRLTable in mongo db
      */
     private static TypeCastingManager<CRLTable> castingManager = new TypeCastingManager<>();
 
-    static {
-        try {
-            CRL_MANAGER = new CrlManager();
-            CRL_MANAGER.init();
-        } catch (CRLException | IOException | OperatorCreationException e) {
-            Log.e(e.getMessage());
-        }
-    }
-
     /**
      * X509 CRL presentation.
      */
     private X509CRL x509CRL;
 
+    /**
+     * Static manager for CRLs.
+     */
+    public static final CrlManager CRL_MANAGER = new CrlManager();
+
+    /**
+     * Private constructor to make this class non-instantiable.
+     */
     private CrlManager() {
+        try {
+            Calendar calendar = Calendar.getInstance();
+            Date thisUpdate = calendar.getTime();
+            calendar.add(Calendar.DAY_OF_MONTH,
+                    Integer.parseInt(NEXT_UPDATE_INTERVAL));
+            byte[] data = CRL_ISSUER.generate(thisUpdate, calendar.getTime(), Collections.emptyList());
+            ACCOUNT_DB_MANAGER.insertRecord(Constants.CRL_TABLE,
+                    castingManager.convertObjectToMap(new CRLTable(thisUpdate, new Binary(data))));
+            setX509CRL(data);
+        } catch (CRLException | IOException | OperatorCreationException e) {
+            Log.e(e.getMessage());
+        }
     }
 
     /**
-     * Revokes specified serial numbers.
+     * Revokes specified serial numbers. Puts them to database.
      *
-     * @param serialNumber specified var args serial numbers from 0.
+     * @param serialNumbers specified var args serial numbers from 0.
      */
-    public void revoke(String... serialNumber) throws CRLException, IOException, OperatorCreationException {
+    public void revoke(String... serialNumbers) throws CRLException, IOException, OperatorCreationException {
         if (x509CRL != null) {
             update(x509CRL.getThisUpdate(),
                     CRL_ISSUER.generate(x509CRL.getThisUpdate(), x509CRL.getNextUpdate(),
-                            x509CRL.getRevokedCertificates(), serialNumber));
+                            x509CRL.getRevokedCertificates(), serialNumbers));
         }
     }
 
     /**
-     * Check if last update is before CRL this update.
+     * Checks last update less than crl this update and returns response payload,
+     * including this update, next update, and CRL in DER encoding.
+     */
+    Map<String, Object> getPayload(String lastUpdate) throws ServerException.PreconditionFailedException, CRLException {
+        if (checkLastUpdate(lastUpdate) && x509CRL != null) {
+            Map<String, Object> responsePayload = new HashMap<>();
+            responsePayload.put(Constants.REQ_THIS_UPDATE, DATE_FORMAT.format(x509CRL.getThisUpdate()));
+            responsePayload.put(Constants.REQ_NEXT_UPDATE, DATE_FORMAT.format(x509CRL.getNextUpdate()));
+            responsePayload.put(Constants.REQ_CRL, new CRL(DER, x509CRL.getEncoded()));
+            return responsePayload;
+        }
+        return Collections.emptyMap();
+    }
+
+
+    /**
+     * Checks if last update is before CRL this update.
+     *
      * @param lastUpdate specified last update;
      * @return true if before and false - otherwise.
      */
-    boolean checkLastUpdate(String lastUpdate) {
+    private boolean checkLastUpdate(String lastUpdate) {
         boolean checkCondition = false;
         try {
             if (x509CRL != null) {
@@ -100,44 +125,20 @@ public final class CrlManager {
         return checkCondition;
     }
 
-    /**
-     * Returns response payload, including this update, next update, and CRL in DER encoding.
-     */
-    Map<String, Object> getPayload() throws ServerException.PreconditionFailedException, CRLException {
-        if (x509CRL != null) {
-            Map<String, Object> responsePayload = new HashMap<>();
-            responsePayload.put(Constants.REQ_THIS_UPDATE, DATE_FORMAT.format(x509CRL.getThisUpdate()));
-            responsePayload.put(Constants.REQ_NEXT_UPDATE, DATE_FORMAT.format(x509CRL.getNextUpdate()));
-            responsePayload.put(Constants.REQ_CRL, new CRL(DER, x509CRL.getEncoded()));
-            return responsePayload;
-        }
-        return Collections.emptyMap();
-    }
 
     /**
      * Updates CRLTable with specified this update and binary CRL data.
      */
     void update(Date thisUpdate, byte[] data) throws CRLException {
-        CRLTable crlTable = castingManager.convertMaptoObject(
-                ACCOUNT_DB_MANAGER.selectRecord(Constants.CRL_TABLE, new HashMap<>()).get(0), new CRLTable());
-        crlTable.setThisUpdate(thisUpdate);
-        crlTable.setBinaryData(new Binary(data));
-        ACCOUNT_DB_MANAGER.updateRecord(Constants.CRL_TABLE, castingManager.convertObjectToMap(crlTable));
-        setX509CRL(data);
-    }
-
-    /**
-     * Create CRL with default options;
-     */
-    private void init() throws CRLException, IOException, OperatorCreationException {
-        Calendar calendar = Calendar.getInstance();
-        Date thisUpdate = calendar.getTime();
-        calendar.add(Calendar.DAY_OF_MONTH,
-                Integer.parseInt(NEXT_UPDATE_INTERVAL));
-        byte[] data = CRL_ISSUER.generate(thisUpdate, calendar.getTime(), Collections.emptyList());
-        ACCOUNT_DB_MANAGER.insertRecord(Constants.CRL_TABLE,
-                castingManager.convertObjectToMap(new CRLTable(thisUpdate, new Binary(data))));
-        setX509CRL(data);
+        ArrayList<HashMap<String, Object>> crlList = ACCOUNT_DB_MANAGER.selectRecord(Constants.CRL_TABLE,
+                new HashMap<>());
+        if (crlList != null && !crlList.isEmpty()) {
+            CRLTable crlTable = castingManager.convertMaptoObject(crlList.get(0), new CRLTable());
+            crlTable.setThisUpdate(thisUpdate);
+            crlTable.setBinaryData(new Binary(data));
+            ACCOUNT_DB_MANAGER.updateRecord(Constants.CRL_TABLE, castingManager.convertObjectToMap(crlTable));
+            setX509CRL(data);
+        }
     }
 
     /**
@@ -148,7 +149,7 @@ public final class CrlManager {
     }
 
     /**
-     * Static inner class for CBOR Crl presentation.
+     * Utility class for CBOR Crl presentation.
      */
     private static final class CRL {
 
@@ -156,7 +157,7 @@ public final class CrlManager {
 
         private final byte[] data;
 
-        public CRL(String encoding, byte[] data) {
+        CRL(String encoding, byte[] data) {
             this.encoding = encoding;
             this.data = data;
         }
@@ -169,5 +170,4 @@ public final class CrlManager {
             return data;
         }
     }
-
 }
index a274784..13a51a2 100644 (file)
@@ -47,7 +47,8 @@ import static org.iotivity.cloud.accountserver.resources.credprov.cert.Certifica
 import static org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager.CRL_MANAGER;
 
 /**
- * Class is responsible for handling requests GET and POST for CRL data.
+ * Class is used working with POST and GET requests and
+ * handles CRL requests.
  */
 public class CrlResource extends Resource {
 
@@ -83,7 +84,20 @@ public class CrlResource extends Resource {
     }
 
     /**
-     * Handles GET request and sends response back to the client.
+     * Method handles GET requests with specified format:
+     * GET /oic/credprov/crl?lu=20170701000000
+     * Checks if “lu” value is not after the latest update.
+     * If so, response with the latest CRL, otherwise response error (e.g. 4.04 Not Found)
+     * And response of next format:
+     * 2.05 CONTENTS
+     * {
+     *      “tu” : “20160711000000”,
+     *      “nu” : “20161011000000”,
+     *      “crl” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded CRL Binary>”
+     *       }
+     * }
      */
     private IResponse handleGetRequest(IRequest request)
             throws ServerException {
@@ -91,11 +105,13 @@ public class CrlResource extends Resource {
         IResponse iResponse = MessageBuilder.createResponse(request, ResponseStatus.NOT_FOUND);
         if (queryData != null) {
             List<String> lastUpdateList = queryData.get(Constants.REQ_LAST_UPDATE);
-            if (lastUpdateList != null && !lastUpdateList.isEmpty() &&
-                    CRL_MANAGER.checkLastUpdate(lastUpdateList.get(0))) {
+            if (lastUpdateList != null && !lastUpdateList.isEmpty()) {
                 try {
-                    iResponse = MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
-                            ContentFormat.APPLICATION_CBOR, MAP_CBOR.encodingPayloadToCbor(CRL_MANAGER.getPayload()));
+                    Map<String, Object> payload = CRL_MANAGER.getPayload(lastUpdateList.get(0));
+                    if (!payload.isEmpty()) {
+                        iResponse = MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+                                ContentFormat.APPLICATION_CBOR, MAP_CBOR.encodingPayloadToCbor(payload));
+                    }
                 } catch (CRLException e) {
                     Log.e(e.getMessage());
                 }
@@ -105,42 +121,63 @@ public class CrlResource extends Resource {
     }
 
     /**
-     * Handles POST requests and sends back CRL data in response.
+     * Handles POST requests of next formats:
+     * POST /oic/credprov/crl
+     * {
+     *      “tu” : “20160727000000”,
+     *      “nu” : “20161027000000”,
+     *      “rcsn” : “123456”
+     * }
+     * AND
+     * POST /oic/credprov/crl
+     * {
+     *      “tu” : “20160727000000”,
+     *      “nu” : “20161027000000”,
+     *      “crl” : {
+     *          “encoding” : “oic.sec.encoding.base64”,
+     *          “data” : “<Base64 encoded New CRL Binary>”
+     *       }
+     * }
+     * And responds back with 2.04 CHANGED if everything is ok, and PRECONDITION_FAILED - otherwise
      */
     private IResponse handlePostRequest(IRequest request)
             throws ServerException {
-        Map<String, Object> payloadData = MAP_CBOR
-                .parsePayloadFromCbor(request.getPayload(), HashMap.class);
-        Object thisUpdate = payloadData.get(Constants.REQ_THIS_UPDATE);
-        Object nextUpdate = payloadData.get(Constants.REQ_NEXT_UPDATE);
+        byte[] requestPayload = request.getPayload();
         IResponse response = MessageBuilder.createResponse(request, ResponseStatus.PRECONDITION_FAILED);
-        if (thisUpdate != null && thisUpdate instanceof String && nextUpdate != null && nextUpdate instanceof String) {
-            Date thisUpdateDate;
-            try {
-                thisUpdateDate = DATE_FORMAT.parse(thisUpdate.toString());
-                DATE_FORMAT.parse(nextUpdate.toString());
-                Object reqSerialNumber = payloadData.get(Constants.REQ_SERIAL_NUMBER);
-                Object crl = payloadData.get(Constants.REQ_CRL);
-                if (reqSerialNumber != null && reqSerialNumber instanceof List) {
-                    CRL_MANAGER.revoke(((List<String>) reqSerialNumber).toArray(new String[]{}));
-                    response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
-                } else if (crl != null && crl instanceof Map) {
-                    Object encoding = ((Map<String, Object>) crl).get(Constants.ENCODING);
-                    Object crlData = ((Map<String, Object>) crl).get(Constants.DATA);
-                    if (encoding != null && encoding instanceof String && crlData != null && crlData instanceof byte[]) {
-                        try {
-                            if (encoding.equals(BASE_64)) {
-                                crlData = Base64.decode((byte[]) crlData);
-                            }
-                            CRL_MANAGER.update(thisUpdateDate, (byte[]) crlData);
+        if (requestPayload != null) {
+            Map<String, Object> payloadData = MAP_CBOR
+                    .parsePayloadFromCbor(request.getPayload(), HashMap.class);
+            if (payloadData != null) {
+                Object thisUpdate = payloadData.get(Constants.REQ_THIS_UPDATE);
+                Object nextUpdate = payloadData.get(Constants.REQ_NEXT_UPDATE);
+                if (thisUpdate != null && thisUpdate instanceof String && nextUpdate != null && nextUpdate instanceof String) {
+                    Date thisUpdateDate;
+                    try {
+                        thisUpdateDate = DATE_FORMAT.parse(thisUpdate.toString());
+                        Object reqSerialNumber = payloadData.get(Constants.REQ_SERIAL_NUMBER);
+                        Object crl = payloadData.get(Constants.REQ_CRL);
+                        if (reqSerialNumber != null && reqSerialNumber instanceof List) {
+                            CRL_MANAGER.revoke(((List<String>) reqSerialNumber).toArray(new String[]{}));
                             response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
-                        } catch (DecoderException e) {
-                            Log.e(e.getMessage() + e.getClass());
+                        } else if (crl != null && crl instanceof Map) {
+                            Object encoding = ((Map<String, Object>) crl).get(Constants.ENCODING);
+                            Object crlData = ((Map<String, Object>) crl).get(Constants.DATA);
+                            if (encoding != null && encoding instanceof String && crlData != null && crlData instanceof byte[]) {
+                                try {
+                                    if (encoding.equals(BASE_64)) {
+                                        crlData = Base64.decode((byte[]) crlData);
+                                    }
+                                    CRL_MANAGER.update(thisUpdateDate, (byte[]) crlData);
+                                    response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
+                                } catch (DecoderException e) {
+                                    Log.e(e.getMessage() + e.getClass());
+                                }
+                            }
                         }
+                    } catch (CRLException | IOException | OperatorCreationException | ParseException e) {
+                        Log.e(e.getMessage() + e.getClass());
                     }
                 }
-            } catch (CRLException | IOException | OperatorCreationException | ParseException e) {
-                Log.e(e.getMessage() + e.getClass());
             }
         }
         return response;
index 0bf7401..71fb1a0 100644 (file)
@@ -21,6 +21,7 @@
  */
 package org.iotivity.cloud.accountserver.x509.cert;
 
+import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.openssl.PEMException;
 import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
@@ -95,8 +96,11 @@ public class CSRParser {
      * Returns common name from csr subject.
      */
     public String getCommonName() {
-        return subject.getRDNs(CN)[0].getFirst().getValue().toString();
-
+        AttributeTypeAndValue rdn = subject.getRDNs(CN)[0].getFirst();
+        if (rdn != null) {
+            return rdn.getValue().toString();
+        }
+        return null;
     }
 
     /**
index 041bea7..7aed99f 100644 (file)
@@ -58,31 +58,31 @@ public class CertificateBuilder {
     /**
      * Attribute for X500Name subject.
      */
-    private X500Name subject;
+    private final X500Name subject;
 
     /**
      * Attribute for public key.
      */
-    private PublicKey publicKey;
+    private final PublicKey publicKey;
 
     /**
      * Attribute for certificate extension.
      */
-    private CertificateExtension extension;
+    private final CertificateExtension extension;
 
     /**
      * Constructs certificate builder with specified subject
      * public key and certificate extension.
      */
-    public CertificateBuilder(X500Name subject,
-                              PublicKey publicKey, CertificateExtension extension) {
+    public CertificateBuilder(X500Name subject, PublicKey publicKey, CertificateExtension extension) {
         this.subject = subject;
         this.publicKey = publicKey;
         this.extension = extension;
     }
 
     /**
-     * Builds X509Certificate with default root key.
+     * Builds X509Certificate, issued by CA issuer, with specific subject and publick key
+     * Adds extension during build.
      */
     public X509Certificate build() throws CertIOException, GeneralSecurityException, OperatorCreationException {
         X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
@@ -120,6 +120,4 @@ public class CertificateBuilder {
                 Integer.parseInt(NOT_AFTER_INTERVAL));
         return calendar.getTime();
     }
-
-
 }
\ No newline at end of file
index 8172a19..86b9ff8 100644 (file)
@@ -69,8 +69,6 @@ public class CertificateExtension {
 
     /**
      * Returns ASN1Encodable attribute value.
-     *
-     * @return
      */
     ASN1Encodable getValue() {
         return value;
index 6e4df99..3ea06b2 100644 (file)
@@ -36,7 +36,7 @@ import java.util.Date;
 import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.CA_ISSUER;
 
 /**
- * Class is used for generating CRL with specified parameters.
+ * Class is used for generating CRLs with specified parameters.
  */
 public final class CrlIssuer {
     /**
@@ -45,7 +45,7 @@ public final class CrlIssuer {
     public static final CrlIssuer CRL_ISSUER = new CrlIssuer();
 
     /**
-     * Creates new instance of CRL issuer.
+     * Private constructor to make class non-instantiable.
      */
     private CrlIssuer() {
     }
@@ -55,7 +55,6 @@ public final class CrlIssuer {
      */
     public byte[] generate(Date thisUpdate, Date nextUpdate, Collection<? extends X509CRLEntry> certs,
                            String... serialNumbers) throws IOException, OperatorCreationException {
-        byte[] crl;
         X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(CA_ISSUER,
                 thisUpdate);
         crlBuilder.setNextUpdate(nextUpdate);
@@ -67,8 +66,8 @@ public final class CrlIssuer {
         for (String serialNumber : serialNumbers) {
             crlBuilder.addCRLEntry(new BigInteger(serialNumber), new Date(), 0);
         }
-        crl = crlBuilder.build(CertificateBuilder.SIGNER_BUILDER.
+        return crlBuilder.build(CertificateBuilder.SIGNER_BUILDER.
                 build(CertificateStorage.ROOT_PRIVATE_KEY)).getEncoded();
-        return crl;
     }
+
 }
\ No newline at end of file
index 62bdca5..552eb7a 100644 (file)
  */
 package org.iotivity.cloud.accountserver.resources.account.credprov.cert;
 
-import org.bouncycastle.util.encoders.Base64;
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
 import org.iotivity.cloud.accountserver.db.TokenTable;
-import org.iotivity.cloud.accountserver.resources.account.credprov.crl.CrlResourceTest;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateResource;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
-import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlResource;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.accountserver.x509.cert.Utility;
 import org.iotivity.cloud.base.OICConstants;
@@ -56,38 +53,32 @@ import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.math.BigInteger;
-import java.security.cert.*;
-import java.util.*;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
-import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
-import static org.junit.Assert.*;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.CERTIFICATE_FACTORY;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.KEYSTORE_FILE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
 public class CertificateResourceTest {
 
-    private static final String COMMON_NAME = "OU=OCF Device CA, O=Samsung, C=KR, CN=uuid:B371C481-38E6-4D47-8320-7688D8A5B58C";
-
+    public static final String COMMON_NAME = "OU=OCF Device CA, O=Samsung, C=KR, CN=uuid:B371C481-38E6-4D47-8320-7688D8A5B58C";
+    public static final String DEVICE_ID = "B371C481-38E6-4D47-8320-7688D8A5B58C";
     private static final String CERTIFICATE_URI = OICConstants.CREDPROV_CERT_FULL_URI;
-
-    private static final String DEVICE_ID = "B371C481-38E6-4D47-8320-7688D8A5B58C";
-
+    private static CertificateResource certificateResource = new CertificateResource();
+    private static TypeCastingManager<TokenTable> castingManager = new TypeCastingManager<>();
     private CoapDevice mMockDevice = mock(CoapDevice.class);
-
     private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
-
     private IResponse mResponse = null;
-
     private CountDownLatch mLatch = new CountDownLatch(
             1);
-
-    private static CertificateResource certificateResource = new CertificateResource();
-
     private byte[] csr;
 
-    private static TypeCastingManager<TokenTable> castingManager = new TypeCastingManager<>();
-
     static void createToken() {
         TokenTable certificateTable = new TokenTable();
         certificateTable.setDid(DEVICE_ID);
@@ -99,6 +90,7 @@ public class CertificateResourceTest {
     @AfterClass
     public static void after() {
         KEYSTORE_FILE.delete();
+        AccountDBManager.getInstance().deleteRecord(Constants.CERTIFICATE_TABLE, new HashMap<>());
     }
 
     @BeforeClass
@@ -142,8 +134,6 @@ public class CertificateResourceTest {
                 Object[] args = invocation.getArguments();
                 CoapResponse resp = (CoapResponse) args[0];
                 mResponse = resp;
-
-
                 mLatch.countDown();
                 return null;
             }
@@ -247,67 +237,6 @@ public class CertificateResourceTest {
         assertTrue(methodCheck(mResponse, ResponseStatus.BAD_REQUEST));
     }
 
-    Map<String, Object> payloadData;
-
-    Map<String, Object> crlMap;
-
-    byte[] data;
-
-    X509CRL crlX509;
-
-    @Test
-    public void testReIssueBase64() throws CRLException, CertificateException {
-        IRequest request = csrRequest(DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
-        certificateResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-
-        Map<String, Object> payloadData = mCbor
-                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
-        List<BigInteger> serialNumbers = new ArrayList<>();
-        Map<String, Object> certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
-        InputStream in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
-        X509Certificate personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
-        serialNumbers.add(personaleCert.getSerialNumber());
-        serialNumbers.add(personaleCert.getSerialNumber().subtract(BigInteger.ONE));
-
-        request = csrRequest(DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
-        certificateResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        payloadData = mCbor
-                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
-        certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
-        in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
-        personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
-        serialNumbers.add(personaleCert.getSerialNumber());
-
-
-        request = csrRequest(DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
-        certificateResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
-        getTestMethodName();
-        request = CrlResourceTest.crlRequest(RequestMethod.GET, CrlResourceTest.CRL_URI, CrlResourceTest.CRL_URI_QUERY);
-        CrlResource crlResource = new CrlResource();
-        crlResource.onDefaultRequestReceived(mMockDevice, request);
-        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-        hashmapCheck(mResponse, Constants.ENCODING);
-        hashmapCheck(mResponse, Constants.DATA);
-        if (mResponse.getPayload() != null) {
-            payloadData = mCbor
-                    .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
-            crlMap = (Map<String, Object>) payloadData.get(Constants.REQ_CRL);
-            data = (byte[]) crlMap.get(Constants.DATA);
-            crlX509 = (X509CRL) CERTIFICATE_FACTORY.generateCRL(new ByteArrayInputStream(data));
-        }
-
-        assertEquals(DER, crlMap.get(Constants.ENCODING));
-        assertNotNull(data);
-        Set<? extends X509CRLEntry> entries = crlX509.getRevokedCertificates();
-        Iterator<? extends X509CRLEntry> iterator = entries.iterator();
-        while (iterator.hasNext()) {
-            assertTrue(serialNumbers.contains(iterator.next().getSerialNumber()));
-        }
-    }
-
     @Test
     public void testMethodNotAllowed() {
         IRequest request = csrRequest(DEVICE_ID, CertificateConstants.DER, csr, RequestMethod.GET, true);
@@ -364,7 +293,24 @@ public class CertificateResourceTest {
         return request;
     }
 
-    private static class CSR {
+    private boolean methodCheck(IResponse response,
+                                ResponseStatus responseStatus) {
+        if (responseStatus == response.getStatus())
+            return true;
+        else
+            return false;
+    }
+
+    private boolean hashmapCheck(IResponse response, String propertyName) {
+        HashMap<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(response.getPayload(), HashMap.class);
+        if (payloadData.containsKey(propertyName))
+            return true;
+        else
+            return false;
+    }
+
+    public static class CSR {
         String encoding;
 
         byte[] data;
@@ -394,21 +340,4 @@ public class CertificateResourceTest {
         }
     }
 
-    private boolean methodCheck(IResponse response,
-                                ResponseStatus responseStatus) {
-        if (responseStatus == response.getStatus())
-            return true;
-        else
-            return false;
-    }
-
-    private boolean hashmapCheck(IResponse response, String propertyName) {
-        HashMap<String, Object> payloadData = mCbor
-                .parsePayloadFromCbor(response.getPayload(), HashMap.class);
-        if (payloadData.containsKey(propertyName))
-            return true;
-        else
-            return false;
-    }
-
 }
index 1afb0ef..d548d1f 100644 (file)
@@ -27,6 +27,8 @@ import org.bouncycastle.util.encoders.Base64;
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
 import org.iotivity.cloud.accountserver.db.CRLTable;
+import org.iotivity.cloud.accountserver.resources.account.credprov.cert.CertificateResourceTest;
+import org.iotivity.cloud.accountserver.resources.account.credprov.cert.GenerateCSR;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateResource;
 import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
@@ -34,6 +36,7 @@ import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager;
 import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlResource;
 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
 import org.iotivity.cloud.accountserver.x509.crl.CrlIssuer;
+import org.iotivity.cloud.base.OICConstants;
 import org.iotivity.cloud.base.device.CoapDevice;
 import org.iotivity.cloud.base.protocols.IRequest;
 import org.iotivity.cloud.base.protocols.IResponse;
@@ -43,7 +46,9 @@ import org.iotivity.cloud.base.protocols.enums.ContentFormat;
 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
 import org.iotivity.cloud.util.Cbor;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -52,6 +57,7 @@ import org.mockito.stubbing.Answer;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -61,6 +67,7 @@ import java.security.Security;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509CRL;
 import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
 import java.text.ParseException;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
@@ -84,13 +91,22 @@ public class CrlResourceTest {
     public static final String CRL_URI_QUERY_CONDITION_FALSE = "lu=21160726210000";
     public static final String CRL_URI_QUERY_PARSE_ERROR = "lu=1231212asdzfg4123123123123123";
     public static final String[] FOR_FULL_CRL = {Constants.REQ_THIS_UPDATE, Constants.REQ_NEXT_UPDATE, Constants.REQ_CRL};
-    public static final PublicKey key = CertificateStorage.ROOT_CERTIFICATE.getPublicKey();
+    public static PublicKey key;
+    static CertificateResource certificateResource;
 
     private static TypeCastingManager<CRLTable> castingManager = new TypeCastingManager<>();
 
-    static {
+    @AfterClass
+    public static void after() {
+        AccountDBManager.getInstance().deleteRecord(Constants.CERTIFICATE_TABLE, new HashMap<>());
+        AccountDBManager.getInstance().deleteRecord(Constants.CRL_TABLE, new HashMap<>());
+    }
+
+    @BeforeClass
+    public static void setUpBefore() {
         Security.insertProviderAt(new BouncyCastleProvider(), 0);
-        new CertificateResource();
+        certificateResource = new CertificateResource();
+        key = CertificateStorage.ROOT_CERTIFICATE.getPublicKey();
     }
 
     /**
@@ -121,11 +137,12 @@ public class CrlResourceTest {
                     payloadData = mCbor
                             .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
                     crlMap = (Map<String, Object>) payloadData.get(Constants.REQ_CRL);
-                    data = (byte[]) crlMap.get(Constants.DATA);
-                    CertificateFactory factory = CertificateFactory.getInstance("X509");
-                    crlX509 = (X509CRL) factory.generateCRL(new ByteArrayInputStream(data));
+                    if (crlMap != null) {
+                        data = (byte[]) crlMap.get(Constants.DATA);
+                        CertificateFactory factory = CertificateFactory.getInstance("X509");
+                        crlX509 = (X509CRL) factory.generateCRL(new ByteArrayInputStream(data));
+                    }
                 }
-
                 mLatch.countDown();
                 return null;
             }
@@ -158,6 +175,73 @@ public class CrlResourceTest {
         return SERIAL_NUMBER;
     }
 
+
+    @Test
+    public void testAeIssueBase64() throws Exception {
+        byte[] csr = GenerateCSR.generatePKCS10(CertificateResourceTest.COMMON_NAME, false);
+        IRequest request = csrRequest(CertificateResourceTest.DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
+        certificateResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        Map<String, Object> payloadData = mCbor
+                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
+        List<BigInteger> serialNumbers = new ArrayList<>();
+        Map<String, Object> certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
+        InputStream in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
+        X509Certificate personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
+        serialNumbers.add(personaleCert.getSerialNumber());
+        serialNumbers.add(personaleCert.getSerialNumber().subtract(BigInteger.ONE));
+        request = csrRequest(CertificateResourceTest.DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
+        certificateResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        payloadData = mCbor
+                .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
+        certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
+        in = new ByteArrayInputStream(Base64.decode((byte[]) certMap.get(Constants.DATA)));
+        personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
+        serialNumbers.add(personaleCert.getSerialNumber());
+        request = csrRequest(CertificateResourceTest.DEVICE_ID, CertificateConstants.BASE_64, Base64.encode(csr), RequestMethod.POST, true);
+        certificateResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+        getTestMethodName();
+        request = CrlResourceTest.crlRequest(RequestMethod.GET, CrlResourceTest.CRL_URI, CrlResourceTest.CRL_URI_QUERY);
+        CrlResource crlResource = new CrlResource();
+        crlResource.onDefaultRequestReceived(mMockDevice, request);
+        assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+        hashmapCheck(mResponse, Constants.ENCODING);
+        hashmapCheck(mResponse, Constants.DATA);
+        if (mResponse.getPayload() != null) {
+            payloadData = mCbor
+                    .parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
+            crlMap = (Map<String, Object>) payloadData.get(Constants.REQ_CRL);
+            data = (byte[]) crlMap.get(Constants.DATA);
+            crlX509 = (X509CRL) CERTIFICATE_FACTORY.generateCRL(new ByteArrayInputStream(data));
+        }
+        assertEquals(DER, crlMap.get(Constants.ENCODING));
+        assertNotNull(data);
+        Set<? extends X509CRLEntry> entries = crlX509.getRevokedCertificates();
+        Iterator<? extends X509CRLEntry> iterator = entries.iterator();
+        while (iterator.hasNext()) {
+            assertTrue(serialNumbers.contains(iterator.next().getSerialNumber()));
+        }
+    }
+
+    private IRequest csrRequest(String deviceId, String encoding, byte[] data, RequestMethod method, boolean isEncoded) {
+        IRequest request;
+        HashMap<String, Object> payloadData = new HashMap<>();
+        payloadData.put(Constants.REQ_DEVICE_ID, deviceId);
+        CertificateResourceTest.CSR csr = new CertificateResourceTest.CSR();
+        if (isEncoded) {
+            csr.setEncoding(encoding);
+            csr.setData(data);
+            payloadData.put("csr", csr);
+        }
+        request = MessageBuilder.createRequest(method, OICConstants.CREDPROV_CERT_FULL_URI,
+                null, ContentFormat.APPLICATION_CBOR,
+                mCbor.encodingPayloadToCbor(payloadData));
+        return request;
+    }
+
+
     @Test
     public void testCrlGetContent() throws Exception {
         getTestMethodName();
@@ -208,34 +292,6 @@ public class CrlResourceTest {
     }
 
     @Test
-    public void testX509CRL() {
-        Field field;
-        Method m;
-        try {
-            IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
-            crlResource.onDefaultRequestReceived(mMockDevice, request);
-            assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
-            field = CrlManager.class.getDeclaredField("x509CRL");
-            field.setAccessible(true);
-            Object value = field.get(CrlManager.CRL_MANAGER);
-            field.set(CrlManager.CRL_MANAGER, null);
-            request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
-            crlResource.onDefaultRequestReceived(mMockDevice, request);
-            assertTrue(methodCheck(mResponse, ResponseStatus.NOT_FOUND));
-            m = CrlManager.class.getDeclaredMethod("getPayload");
-            m.setAccessible(true);
-            field.set(CrlManager.CRL_MANAGER, null);
-            Object o = m.invoke(CrlManager.CRL_MANAGER);
-            assertEquals(Collections.EMPTY_MAP, o);
-            field.set(CrlManager.CRL_MANAGER, value);
-        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (NoSuchFieldException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Test
     public void testCrlPreconditionFailedException() throws ParseException, IOException, OperatorCreationException {
         getTestMethodName();
         getTestMethodName();
@@ -261,6 +317,7 @@ public class CrlResourceTest {
         getTestMethodName();
         IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
         crlResource.onDefaultRequestReceived(mMockDevice, request);
+        System.out.println("MRESPONSE" + mResponse.getStatus());
         assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
         String thisUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getThisUpdate());
         String nextUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getNextUpdate());