#New Serial number
-#Thu Aug 25 11:19:40 EEST 2016
+#Wed Sep 07 17:08:34 EEST 2016
keyGeneratorAlgorithm=ECDSA
notAfterInterval=20
securityProvider=BC
ellipticCurve=secp256r1
-crlLocation=keystore{0}crl
keyStoreLocation=keystore{0}certificateStorage.jks
-keystoreType=BKS
nextUpdateInterval=1
signatureAlgorithm=SHA256withECDSA
-crlCN=C\=DE,O\=Samsung
-serialNumber=223
-deviceO=Samsung
-subjectName=uuid\:31313131-3131-3131-3131-313131313131
+keystoreType=BKS
+rootOU=OCF Sub CA
+serialNumber=515
+rootO=Samsung
caAlias=uuid\:31313131-3131-3131-3131-313131313131
-deviceOU=OCF Root CA
+subjectName=uuid\:31313131-3131-3131-3131-313131313131
password=PASSWORD
-deviceC=UK
+rootC=KR
*/
package org.iotivity.cloud.accountserver;
-import java.io.File;
-
import org.iotivity.cloud.base.OICConstants;
+import java.io.File;
+
public class Constants extends OICConstants {
public static final String PROPERTIES_FILE_NAME = "properties"
public static final String RESP_INVITED = "invited";
- public static final String CSR_ENCODING = "csr.encoding";
-
- public static final String CSR_DATA = "csr.data";
-
- public static final String CERT_ENCODING = "cert.encoding";
-
- public static final String CERT_DATA = "cert.data";
-
- public static final String CERTCHAIN_ENCODING = "certchain.encoding";
+ public static final String ENCODING = "encoding";
- public static final String CERTCHAIN_DATA = "certchain.data";
+ public static final String DATA = "data";
- public static final String CRL_ENCODING = "crl.encoding";
+ public static final String CERT = "cert";
- public static final String CRL_DATA = "crl.data";
+ public static final String CERT_CHAIN = "certchain";
// static token type
mongoDB.createIndex(Constants.CERTIFICATE_TABLE, keys);
keyField.put(Constants.CERTIFICATE_TABLE, keys);
+ keys = new ArrayList<>();
+ keys.add(Constants.REQ_THIS_UPDATE);
+ mongoDB.createIndex(Constants.CRL_TABLE, keys);
+ keyField.put(Constants.CRL_TABLE, keys);
+
}
public static AccountDBManager getInstance() {
if (!_updateRecord(tableName, replace))
throw new InternalServerErrorException(
- "Database record update failed");
+ "Database record updateX509CRL failed");
}
*/
package org.iotivity.cloud.accountserver.db;
+import org.bson.types.Binary;
+
import java.util.Date;
public class CRLTable {
private Date thisUpdate;
- public CRLTable(Date thisUpdate) {
+ private Binary binaryData;
+
+ public CRLTable() {
+ }
+
+ public CRLTable(Date thisUpdate, Binary binaryData) {
this.thisUpdate = thisUpdate;
+ this.binaryData = binaryData;
}
public Date getThisUpdate() {
public void setThisUpdate(Date thisUpdate) {
this.thisUpdate = thisUpdate;
}
+
+ public Binary getBinaryData() {
+ return binaryData;
+ }
+
+ public void setBinaryData(Binary binaryData) {
+ this.binaryData = binaryData;
+ }
+
+ @Override
+ public String toString() {
+ return "CRLTable{" +
+ "thisUpdate=" + thisUpdate +
+ ", binaryData=" + binaryData +
+ '}';
+ }
}
if (collection.findOneAndReplace(filter, record) == null) {
- Log.w("DB update failed due to no matched record!");
+ Log.w("DB updateX509CRL failed due to no matched record!");
return false;
}
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * // http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
package org.iotivity.cloud.accountserver.resources.credprov.cert;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.db.AccountDBManager;
+import org.iotivity.cloud.accountserver.x509.cert.Utility;
+import org.iotivity.cloud.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.Properties;
+
+import static java.security.cert.CertificateFactory.getInstance;
+
/**
- * Created by octavian on 22.08.16.
+ * This utility class is used for getting all properties from properties file.
*/
-public interface CertificateConstants {
+public final class CertificateConstants {
- public static final String BASE_64 = "oic.sec.encoding.base64";
+ public static final Properties PROPERTIES = new Properties();
+ /**
+ * Load properties from specified properties file.
+ */
+ static {
+ try {
+ PROPERTIES.load(new FileInputStream(Constants.PROPERTIES_FILE_NAME));
+ } catch (IOException e) {
+ Log.e(e.getMessage());
+ }
+ }
+
+ public static final String BASE_64 = "oic.sec.encoding.base64";
public static final String DER = "oic.sec.encoding.der";
+ public static final String SECURITY_PROVIDER = PROPERTIES.getProperty("securityProvider");
+
+ public static final String NOT_AFTER_INTERVAL = PROPERTIES.getProperty("notAfterInterval");
+
+ public static final String NEXT_UPDATE_INTERVAL = PROPERTIES.getProperty("nextUpdateInterval");
+
+ public static final String SIGNATURE_ALGORITHM = PROPERTIES.getProperty("signatureAlgorithm");
+
+ static final String KEYSTORE_TYPE = PROPERTIES.getProperty("keystoreType");
+
+ static final String CA_ALIAS = PROPERTIES.getProperty("caAlias");
+
+ static final String CURVE = PROPERTIES.getProperty("ellipticCurve");
+
+ static final String KEY_GENERATOR_ALGORITHM = PROPERTIES.getProperty("keyGeneratorAlgorithm");
+
+ public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
+
+ public static final X500Name CA_ISSUER = Utility.getName(PROPERTIES.getProperty("subjectName"),
+ PROPERTIES.getProperty("rootC"), PROPERTIES.getProperty("rootO"), PROPERTIES.getProperty("rootOU"));
+
+ public static final AccountDBManager ACCOUNT_DB_MANAGER = AccountDBManager.getInstance();
+
+ public static CertificateFactory CERTIFICATE_FACTORY;
+
+ static {
+ try {
+ CERTIFICATE_FACTORY = getInstance("X509");
+ } catch (CertificateException e) {
+ Log.e(e.getMessage());
+ }
+ }
+
+ /**
+ * Path to keystore 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.
+ */
+ public static void set(String property, String value) {
+ PROPERTIES.setProperty(property, value);
+ try {
+ PROPERTIES.store(new FileOutputStream(Constants.PROPERTIES_FILE_NAME), "New Serial number");
+ } catch (IOException e) {
+ Log.e(e.getMessage());
+ }
+ }
+ private CertificateConstants() {
+ throw new AssertionError();
+ }
}
*/
package org.iotivity.cloud.accountserver.resources.credprov.cert;
-import org.iotivity.cloud.accountserver.Constants;
-import org.iotivity.cloud.accountserver.db.AccountDBManager;
import org.iotivity.cloud.accountserver.db.CertificateTable;
import org.iotivity.cloud.accountserver.util.TypeCastingManager;
+import org.iotivity.cloud.accountserver.x509.cert.Utility;
+
+import java.math.BigInteger;
+import java.util.Date;
+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.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
+ * Table by specified device id.
+ */
+final class CertificateManager {
-import java.util.*;
+ /**
+ * Type casting manager for converting CertificateTable object tot map
+ */
+ private static final TypeCastingManager<CertificateTable> CERTIFICATE_TABLE_TYPE_CASTING_MANAGER =
+ new TypeCastingManager<>();
-public final class CertificateManager {
+ /**
+ * Class attribute as payload for response.
+ */
private final Map<String, Object> payLoad;
- private TypeCastingManager<CertificateTable> castingManager = new TypeCastingManager<>();
-
- public Map<String, Object> getPayLoad() {
- return payLoad;
- }
-
- public void putCert(String encoding, byte[] cert) {
- if (encoding.equals(CertificateConstants.BASE_64)){
- cert = org.bouncycastle.util.encoders.Base64.encode(cert);
- }
- payLoad.put(Constants.CERT_ENCODING, encoding);
- payLoad.put(Constants.CERT_DATA, cert);
-
- }
+ /**
+ * Class attribute to store device id.
+ */
+ private final String deviceId;
- public void putCACert(String encoding, byte[] cacert) {
- if (encoding.equals(CertificateConstants.BASE_64)){
- cacert = org.bouncycastle.util.encoders.Base64.encode(cacert);
- }
- payLoad.put(Constants.CERTCHAIN_ENCODING, encoding);
- payLoad.put(Constants.CERTCHAIN_DATA, cacert);
+ /**
+ * Constructs certificateMananger with specified device id.
+ * @param deviceId specified device identifier for this CertificateManager.
+ */
+ CertificateManager(String deviceId) {
+ payLoad = new HashMap<>();
+ this.deviceId = deviceId;
}
- public void putDeviceId(String di) {
- payLoad.put(Constants.RESP_DEVICE_ID, di);
+ /**
+ * Returns payload for response.
+ */
+ Map<String, Object> getPayLoad() {
+ return payLoad;
}
- public CertificateManager() {
- payLoad = new HashMap<>();
+ /**
+ * Puts for specified key, specified value to
+ * object payload;
+ * @param key specified key value
+ * @param value specified value
+ */
+ public void put(String key, Object value) {
+ payLoad.put(key, value);
}
- public void createCertificate(String serialNumber, Date notAfter, Date notBefore,
- String deviceId, String uid) {
- CertificateTable certificateTable = new CertificateTable(serialNumber,
- notAfter, notBefore, deviceId, uid, false);
- AccountDBManager.getInstance().insertRecord(Constants.CERTIFICATE_TABLE,
- castingManager.convertObjectToMap(certificateTable));
-
+ /**
+ * Saves new certificate to DB with specified columns.
+ *
+ * @param serialNumber specified certificate serial number
+ * @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)));
}
- public void updateCertificate(String serialNumber, boolean revoked) {
- CertificateTable certificateTable = getCertificateTable(serialNumber);
+ /**
+ * Updates certificate table with specified revoked column.
+ * @param certificateTable certificate to be updated.
+ * @param revoked specified value for revoke
+ */
+ void update(CertificateTable certificateTable, boolean revoked) {
certificateTable.setRevoked(revoked);
- AccountDBManager.getInstance().updateRecord(Constants.CERTIFICATE_TABLE,
- castingManager.convertObjectToMap(certificateTable));
-
+ ACCOUNT_DB_MANAGER.updateRecord(CERTIFICATE_TABLE,
+ CERTIFICATE_TABLE_TYPE_CASTING_MANAGER.convertObjectToMap(certificateTable));
}
-
- private CertificateTable getCertificateTable(String serialNumber) {
- CertificateTable certificateTable = new CertificateTable();
- HashMap<String, Object> condition = new HashMap<>();
- condition.put(Constants.KEYFIELD_SN, serialNumber);
- certificateTable = castingManager
- .convertMaptoObject(
- AccountDBManager.getInstance().selectRecord(
- Constants.CERTIFICATE_TABLE, condition).get(0),
- certificateTable);
- return certificateTable;
- }
-
-
- public String getUserID(String deviceId) {
+ /**
+ * Returns certificate from database, according to specified
+ * device id
+ */
+ public CertificateTable getCertificate() {
HashMap<String, Object> condition = new HashMap<>();
- condition.put(Constants.KEYFIELD_DID, deviceId);
- ArrayList<HashMap<String, Object>> recordList = AccountDBManager
- .getInstance().selectRecord(Constants.TOKEN_TABLE, condition);
- Iterator<HashMap<String, Object>> iterator = recordList.iterator();
- String result = null;
- if (iterator.hasNext()) {
- result = iterator.next().get(Constants.KEYFIELD_UUID).toString();
+ condition.put(KEYFIELD_DID, deviceId);
+ condition.put(KEYFIELD_REVOKED, false);
+ List<HashMap<String, Object>> listMap = ACCOUNT_DB_MANAGER.selectRecord(
+ CERTIFICATE_TABLE, condition);
+ if (!listMap.isEmpty()) {
+ return CERTIFICATE_TABLE_TYPE_CASTING_MANAGER
+ .convertMaptoObject(
+ listMap.get(0),
+ new CertificateTable());
+ } else {
+ return null;
}
- return result;
}
}
*/
package org.iotivity.cloud.accountserver.resources.credprov.cert;
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.cert.CertIOException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.encoders.Base64;
import org.iotivity.cloud.accountserver.Constants;
+import org.iotivity.cloud.accountserver.db.CertificateTable;
+import org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager;
import org.iotivity.cloud.accountserver.x509.cert.CSRParser;
import org.iotivity.cloud.accountserver.x509.cert.CertificateBuilder;
-import org.iotivity.cloud.accountserver.x509.cert.CertificatePrivateKeyPair;
-import org.iotivity.cloud.accountserver.x509.crl.CrlIssuer;
+import org.iotivity.cloud.accountserver.x509.cert.CertificateExtension;
+import org.iotivity.cloud.accountserver.x509.cert.Utility;
import org.iotivity.cloud.base.device.Device;
import org.iotivity.cloud.base.exception.ServerException;
import org.iotivity.cloud.base.protocols.IRequest;
import org.iotivity.cloud.util.Log;
import java.io.IOException;
-import java.math.BigInteger;
import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
import java.security.Security;
-import java.security.cert.Certificate;
+import java.security.cert.CRLException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
-import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import static org.iotivity.cloud.accountserver.Constants.*;
-import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage.*;
-
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.BASE_64;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.KEYSTORE_FILE;
+/**
+ * This class provides access for certificate resource.
+ * Devices can send CSR requests in CBOR format to this resource
+ * and get responses in the same format. Response contains device identifier,
+ * personal certificate, issued by CA certificate and certificate chain.
+ */
public class CertificateResource extends Resource {
+ /**
+ * This constant object is used for parsing cbor payload to Map object and to
+ * encoding map object to cbor format.
+ */
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.
+ */
static {
Security.insertProviderAt(new BouncyCastleProvider(), 0);
+ try {
+ if (!KEYSTORE_FILE.exists()) {
+ CertificateStorage.init();
+ } else {
+ CertificateStorage.load();
+ }
+ } catch (GeneralSecurityException | IOException | OperatorCreationException e) {
+ Log.e(e.getMessage());
+ }
}
@Override
srcDevice.sendResponse(response);
}
+ /**
+ * Handles post requests to this resource
+ * @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);
IResponse response = MessageBuilder.createResponse(request, ResponseStatus.BAD_REQUEST);
- if (payloadData.containsKey(CSR_ENCODING)) {
- String encoding = (String) payloadData.get(CSR_ENCODING);
- byte[] data = (byte[]) payloadData.get(CSR_DATA);
- if (data != null) {
- if (encoding.equals(CertificateConstants.BASE_64)) {
- data = Base64.decode(data);
+ 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(data);
+ CSRParser parser = new CSRParser(csrData);
String commonName = parser.getCommonName();
- String[] split = commonName.split(":");
+ String pattern = "^uuid:(.*)$";
+ Pattern r = Pattern.compile(pattern);
+ Matcher m = r.matcher(commonName);
String deviceId = (String) payloadData.get(RESP_DEVICE_ID);
- if (split[0].equals(KEYFIELD_UUID) && split[1].equals(deviceId) && parser.verify()) {
- CertificatePrivateKeyPair privateKeyPair = getRootCertificatePrivateKeyPair();
- X509Certificate x509Certificate = getCertificate(deviceId);
- CertificateManager certificateManager = new CertificateManager();
- BigInteger serialNumber = getNextSerialNumber();
- if (x509Certificate != null) {
- PrivateKey privateKey = privateKeyPair.getPrivateKey();
- CrlIssuer.revokeCertificate(x509Certificate.getSerialNumber(), privateKey);
- certificateManager.updateCertificate(x509Certificate.getSerialNumber().toString(), true);
+ 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);
}
- Date notBefore = getNotBeforeDate();
- Date notAfter = getNotAfterDate();
- CertificateBuilder certBuilder = new CertificateBuilder(
- commonName, parser.getPublicKey(),
- notBefore, notAfter,
- serialNumber, privateKeyPair);
- checkSubjectName(parser, certBuilder);
+ 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 {
- certificateManager.putDeviceId((String) payloadData.get(RESP_DEVICE_ID));
- String uid = certificateManager.getUserID(deviceId);
- certBuilder.setSubjectAltName(Constants.KEYFIELD_USERID + ":" + uid);
- Certificate certificate = certBuilder.build().getX509Certificate();
- CertificateStorage.saveCertificate(certificate, deviceId);
- certificateManager.putCert(encoding, certificate.getEncoded());
- certificateManager.putCACert(encoding, privateKeyPair.getX509Certificate().getEncoded());
- certificateManager.createCertificate(serialNumber.toString(), notBefore, notAfter, deviceId, uid);
+ 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.getNotBefore(),
+ personal.getNotAfter());
response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED,
ContentFormat.APPLICATION_CBOR,
MAP_CBOR.encodingPayloadToCbor(certificateManager.getPayLoad()));
Log.e(e.getMessage());
}
}
-
}
return response;
}
- private void checkSubjectName(CSRParser parser, CertificateBuilder certBuilder) {
- String country = parser.getCountry();
- if (country != null) {
- certBuilder.setSubjectC(country);
+ /**
+ * This class is used for response
+ */
+ private static final class CSR {
+
+ private final String encoding;
+
+ private final byte[] data;
+
+ CSR(String encoding, byte[] data) {
+ this.encoding = encoding;
+ this.data = data;
}
- String organization = parser.getOrganizational();
- if (organization != null) {
- certBuilder.setSubjectO(organization);
+
+ public String getEncoding() {
+ return encoding;
}
- String organizationUnit = parser.getOrganizationalUnit();
- if (organizationUnit != null) {
- certBuilder.setSubjectOU(organizationUnit);
+
+ public byte[] getData() {
+ return data;
}
}
}
*/
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.Constants;
import org.iotivity.cloud.accountserver.x509.cert.CertificateBuilder;
-import org.iotivity.cloud.accountserver.x509.cert.CertificatePrivateKeyPair;
-import org.iotivity.cloud.util.Log;
+import org.iotivity.cloud.accountserver.x509.cert.CertificateExtension;
-import java.io.*;
-import java.math.BigInteger;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
+import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
-import java.text.MessageFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Properties;
-public class CertificateStorage {
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
- public static final Properties PROPERTIES = new Properties();
-
- static {
- try {
- PROPERTIES.load(new FileInputStream(Constants.PROPERTIES_FILE_NAME));
- } catch (IOException e) {
- Log.e(e.getMessage());
- }
- }
-
- public static final String BC = PROPERTIES.getProperty("securityProvider");
+public final class CertificateStorage {
+ /**
+ * This attribute is used to get password to kestore, that stores CA certificate info.
+ * Private key and certificate.
+ */
private static final String PASSWORD = PROPERTIES.getProperty("password");
- public static final String DEVICE_OU = PROPERTIES.getProperty("deviceOU");
-
- public static final String DEVICE_O = PROPERTIES.getProperty("deviceO");
-
- public static final String DEVICE_C = PROPERTIES.getProperty("deviceC");
-
- public static final String KEYSTORE_TYPE = PROPERTIES.getProperty("keystoreType");
-
- public static final String CA_ALIAS = PROPERTIES.getProperty("caAlias");
-
- public static final String SUBJECT_NAME = PROPERTIES.getProperty("subjectName");
-
- private static final File KEYSTORE_FILE = new File(MessageFormat.format(PROPERTIES.getProperty("keyStoreLocation"), File.separator));
+ /**
+ * Keystore object for save, get data from keystore.
+ */
+ private static KeyStore keyStore;
- private static BigInteger SERIAL_NUMBER = new BigInteger(PROPERTIES.getProperty("serialNumber"));
+ public static PrivateKey ROOT_PRIVATE_KEY;
- private static KeyStore keyStore;
+ public static X509Certificate ROOT_CERTIFICATE;
- /**
- * Insert BouncyCastleProvider into 0 position in security provider list.
- * Init KeyStore, Generate CA certificate and save it to keyStore.
- */
- static {
- if (!KEYSTORE_FILE.exists()) {
- try {
- Files.createDirectories(Paths.get("keystore"));
- } catch (IOException e) {
- Log.e(e.getMessage());
- }
- }
- CertificateStorage.init();
- CertificateStorage.load();
- CertificatePrivateKeyPair certificatePrivateKeyPair =
- CertificateStorage.generateCACertificate(DEVICE_C, DEVICE_O, SUBJECT_NAME, DEVICE_OU);
- CertificateStorage.saveCertificatePrivateKey(certificatePrivateKeyPair);
+ private CertificateStorage() {
+ throw new AssertionError();
}
/**
* Init KeyStore. If it does not exists, create it and push to KEYSTORE_FILE.
*/
- private static void init() {
+ static void init() throws GeneralSecurityException, IOException, OperatorCreationException {
+ Files.createDirectories(Paths.get("keystore"));
keyStore = load(null, null);
store();
+ CertificateStorage.generateCACertificate();
+ CertificateStorage.saveCertificatePrivateKey();
}
/**
*
* @return KeyStore instance.
*/
- public static void load() {
- try {
- keyStore = load(new FileInputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
- } catch (FileNotFoundException e) {
- Log.e(e.getMessage());
- }
+ public static void load() throws GeneralSecurityException, IOException {
+ keyStore = load(new FileInputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
+ initRoot();
}
/**
* @param password specified password for opening keystore.
* @return KeyStore instance.
*/
- private static KeyStore load(InputStream is, char[] password) {
- KeyStore keyStore = null;
- try {
- keyStore = KeyStore.getInstance(KEYSTORE_TYPE, BouncyCastleProvider.PROVIDER_NAME);
- keyStore.load(is, password);
- } catch (GeneralSecurityException | IOException e) {
- Log.e(e.getMessage());
- }
+ 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;
}
/**
* Stores keyStore to default file KEYSTORE_FILE with default password.
*/
- public static void store() {
- try {
- store(keyStore, new FileOutputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
- } catch (IOException e) {
- Log.e(e.getMessage());
- }
+ static void store() throws IOException, GeneralSecurityException {
+ store(keyStore, new FileOutputStream(KEYSTORE_FILE), PASSWORD.toCharArray());
}
/**
- * Stores KeyStore to s
+ * Stores KeyStore to file outputstream with specifie password.
*
* @param keyStore
*/
- private static void store(KeyStore keyStore, FileOutputStream out, char[] password) {
- try {
- keyStore.store(out, password);
- out.close();
- } catch (GeneralSecurityException | IOException e) {
- Log.e(e.getMessage());
- }
+ private static void store(KeyStore keyStore, FileOutputStream out, char[] password) throws GeneralSecurityException,
+ IOException {
+ keyStore.store(out, password);
+ out.close();
}
/**
* Generates X509Certificate with PublicKey and PrivateKey
*
- * @param country specified country name
- * @param organization specified organization name
- * @param subjectName specified subject name.
- * @param organizationUnit specified organization unit.
- * @return certificate and private key as fields of CertificatePrivateKeyPair instance.
+ * @return certificate and private key
*/
- private static CertificatePrivateKeyPair generateCACertificate(String country, String organization,
- String subjectName, String organizationUnit) {
- CertificateBuilder rootBuilder = new CertificateBuilder(subjectName, getNotBeforeDate(),
- getNotAfterDate(), getNextSerialNumber());
- rootBuilder.setSubjectC(country);
- rootBuilder.setSubjectO(organization);
- rootBuilder.setSubjectOU(organizationUnit);
- CertificatePrivateKeyPair certificatePrivateKeyPair = null;
- try {
- certificatePrivateKeyPair = rootBuilder.build();
- } catch (GeneralSecurityException | OperatorCreationException | CertIOException e) {
- Log.e(e.getMessage());
+ private static void generateCACertificate() throws GeneralSecurityException,
+ OperatorCreationException, CertIOException {
+ if (ROOT_PRIVATE_KEY == null) {
+ KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, SECURITY_PROVIDER);
+ g.initialize(ECNamedCurveTable.getParameterSpec(CURVE), new SecureRandom());
+ KeyPair pair = g.generateKeyPair();
+ ROOT_PRIVATE_KEY = pair.getPrivate();
+ ROOT_CERTIFICATE = new CertificateBuilder(CA_ISSUER, pair.getPublic(),
+ new CertificateExtension(Extension.basicConstraints, false,
+ new BasicConstraints(true))).build();
}
- return certificatePrivateKeyPair;
}
/**
* Stores certificate and private key to keystore.
- *
- * @param certificatePrivateKeyPair specified certificate private key pair.
- */
- public static void saveCertificatePrivateKey(CertificatePrivateKeyPair certificatePrivateKeyPair) {
- try {
- X509Certificate certificate = certificatePrivateKeyPair.getX509Certificate();
- keyStore.setCertificateEntry(CA_ALIAS, certificate);
- keyStore.setKeyEntry(CA_ALIAS, certificatePrivateKeyPair.getPrivateKey(), PASSWORD.toCharArray(),
- new java.security.cert.Certificate[]{certificate});
- store();
- } catch (GeneralSecurityException e) {
- Log.e(e.getMessage());
- }
- }
-
- public static void saveCertificate(java.security.cert.Certificate certificate, String subjectName) {
- try {
- keyStore.setCertificateEntry(subjectName, certificate);
- store();
- } catch (KeyStoreException e) {
- Log.e(e.getMessage());
- }
- }
-
-
- /**
- * Returns next serial number.
- */
- public static BigInteger getNextSerialNumber() {
- SERIAL_NUMBER = SERIAL_NUMBER.add(BigInteger.ONE);
- PROPERTIES.setProperty("serialNumber", SERIAL_NUMBER.toString());
- try {
- PROPERTIES.store(new FileOutputStream(Constants.PROPERTIES_FILE_NAME), "New Serial number");
- } catch (IOException e) {
- Log.e(e.getMessage());
- }
- return SERIAL_NUMBER;
- }
-
- /**
- * Returns date not before.
- */
- public static Date getNotBeforeDate() {
- return new Date(System.currentTimeMillis());
- }
-
- /**
- * Returns date not after.
- */
- public static Date getNotAfterDate() {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) +
- Integer.parseInt(PROPERTIES.getProperty("notAfterInterval")));
- return calendar.getTime();
- }
-
- /**
- * Returns CertificatePrivateKeyPair for signing user personal certificates.
*/
- public static CertificatePrivateKeyPair getRootCertificatePrivateKeyPair() {
-
- X509Certificate certificate = null;
- PrivateKey privateKey = null;
- try {
- certificate = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
- privateKey = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
- } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e) {
- Log.e(e.getMessage());
- }
- return new CertificatePrivateKeyPair(certificate, privateKey);
+ 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();
}
- /**
- * Returns CertificatePrivateKeyPair for signing user personal certificates.
- */
- public static X509Certificate getCertificate(String alias) {
- X509Certificate certificate = null;
- try {
- certificate = (X509Certificate) keyStore.getCertificate(alias);
- } catch (KeyStoreException e) {
- Log.e(e.getMessage());
- }
- return certificate;
+ private static void initRoot() throws GeneralSecurityException {
+ ROOT_PRIVATE_KEY = (PrivateKey) keyStore.getKey(CA_ALIAS, PASSWORD.toCharArray());
+ ROOT_CERTIFICATE = (X509Certificate) keyStore.getCertificate(CA_ALIAS);
}
}
*/
package org.iotivity.cloud.accountserver.resources.credprov.crl;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bson.types.Binary;
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.credprov.cert.CertificateConstants;
import org.iotivity.cloud.accountserver.util.TypeCastingManager;
-import org.iotivity.cloud.accountserver.x509.crl.CrlParser;
-import org.iotivity.cloud.accountserver.x509.crl.CrlStore;
+import org.iotivity.cloud.base.exception.ServerException;
import org.iotivity.cloud.util.Log;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRL;
import java.text.ParseException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
-import static java.util.Collections.EMPTY_MAP;
-import static org.iotivity.cloud.accountserver.x509.crl.CrlParser.DATE_FORMAT;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
+import static org.iotivity.cloud.accountserver.x509.crl.CrlIssuer.CRL_ISSUER;
+/**
+ * Class is used for managing CRLs(creation, revoke, update)
+ */
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;
+
private CrlManager() {
- throw new AssertionError();
}
- public static boolean checkLastUpdate(String lastUpdate) {
+ /**
+ * Revokes specified serial numbers.
+ *
+ * @param serialNumber specified var args serial numbers from 0.
+ */
+ public void revoke(String... serialNumber) throws CRLException, IOException, OperatorCreationException {
+ if (x509CRL != null) {
+ update(x509CRL.getThisUpdate(),
+ CRL_ISSUER.generate(x509CRL.getThisUpdate(), x509CRL.getNextUpdate(),
+ x509CRL.getRevokedCertificates(), serialNumber));
+ }
+ }
+
+ /**
+ * Check if last update is before CRL this update.
+ * @param lastUpdate specified last update;
+ * @return true if before and false - otherwise.
+ */
+ boolean checkLastUpdate(String lastUpdate) {
boolean checkCondition = false;
try {
- checkCondition = CrlStore.checkLastUpdate(DATE_FORMAT.parse(lastUpdate));
+ if (x509CRL != null) {
+ checkCondition = DATE_FORMAT.parse(lastUpdate).before(x509CRL.getThisUpdate());
+ }
} catch (ParseException e) {
Log.e(e.getMessage());
}
return checkCondition;
}
- public static Map<String, Object> getCrlInfo() {
- byte[] crl = CrlStore.load();
- if (crl == null) {
- return EMPTY_MAP;
+ /**
+ * 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;
}
- CrlParser parser = new CrlParser(crl);
- Map<String, Object> responsePayload = new HashMap<>();
- responsePayload.put(Constants.REQ_THIS_UPDATE, DATE_FORMAT.format(parser.getThisUpdate()));
- responsePayload.put(Constants.REQ_NEXT_UPDATE, DATE_FORMAT.format(parser.getNextUpdate()));
- responsePayload.put(Constants.CRL_ENCODING, CertificateConstants.DER);
- responsePayload.put(Constants.CRL_DATA, crl);
- 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);
}
- public static void createCRL(Date thisUpdate) {
- CRLTable crlTable = new CRLTable(thisUpdate);
- AccountDBManager.getInstance().insertRecord(Constants.CRL_TABLE,
- castingManager.convertObjectToMap(crlTable));
+ /**
+ * 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);
+ }
+
+ /**
+ * Updates currect x509 CRL state by parsing specified data.
+ */
+ private void setX509CRL(byte[] data) throws CRLException {
+ x509CRL = (X509CRL) CERTIFICATE_FACTORY.generateCRL(new ByteArrayInputStream(data));
+ }
+
+ /**
+ * Static inner class for CBOR Crl presentation.
+ */
+ private static final class CRL {
+
+ private final String encoding;
+
+ private final byte[] data;
+
+ public CRL(String encoding, byte[] data) {
+ this.encoding = encoding;
+ this.data = data;
+ }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
}
}
package org.iotivity.cloud.accountserver.resources.credprov.crl;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.util.encoders.Base64;
+import org.bouncycastle.util.encoders.DecoderException;
import org.iotivity.cloud.accountserver.Constants;
-import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants;
-import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
-import org.iotivity.cloud.accountserver.x509.crl.CrlIssuer;
import org.iotivity.cloud.base.device.Device;
import org.iotivity.cloud.base.exception.ServerException;
import org.iotivity.cloud.base.protocols.IRequest;
import org.iotivity.cloud.util.Cbor;
import org.iotivity.cloud.util.Log;
+import java.io.IOException;
+import java.security.cert.CRLException;
import java.text.ParseException;
import java.util.*;
-import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage.PROPERTIES;
-import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage.getRootCertificatePrivateKeyPair;
-import static org.iotivity.cloud.accountserver.x509.crl.CrlParser.DATE_FORMAT;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.BASE_64;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.DATE_FORMAT;
+import static org.iotivity.cloud.accountserver.resources.credprov.crl.CrlManager.CRL_MANAGER;
+/**
+ * Class is responsible for handling requests GET and POST for CRL data.
+ */
public class CrlResource extends Resource {
- private static final Cbor<HashMap<String, Object>> MAP_CBOR = new Cbor<>();
-
- static {
- Calendar calendar = Calendar.getInstance();
- Date thisUpdate = calendar.getTime();
- calendar.add(Calendar.DAY_OF_MONTH,
- Integer.parseInt(PROPERTIES.getProperty("nextUpdateInterval")));
- Date nextUpdate = calendar.getTime();
- CrlIssuer.generate(PROPERTIES.getProperty("crlCN"), thisUpdate,
- nextUpdate, getRootCertificatePrivateKeyPair().getPrivateKey());
- CrlManager.createCRL(thisUpdate);
- }
+ /**
+ * CBOR container with help of map presentation.
+ */
+ private static final Cbor<Map<String, Object>> MAP_CBOR = new Cbor<>();
+ /**
+ * Creates resource for handling CRL requests(GET and POST)
+ */
public CrlResource() {
super(Arrays.asList(Constants.PREFIX_OIC,
Constants.CREDPROV_URI, Constants.REQ_CRL));
srcDevice.sendResponse(response);
}
+ /**
+ * Handles GET request and sends response back to the client.
+ */
private IResponse handleGetRequest(IRequest request)
throws ServerException {
HashMap<String, List<String>> queryData = request.getUriQueryMap();
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() && CrlManager.checkLastUpdate(lastUpdateList.get(0))) {
- System.out.println("LAST DATE = " + lastUpdateList.get(0));
- iResponse = MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
- ContentFormat.APPLICATION_CBOR, MAP_CBOR.encodingPayloadToCbor(CrlManager.getCrlInfo()));
+ if (lastUpdateList != null && !lastUpdateList.isEmpty() &&
+ CRL_MANAGER.checkLastUpdate(lastUpdateList.get(0))) {
+ try {
+ iResponse = MessageBuilder.createResponse(request, ResponseStatus.CONTENT,
+ ContentFormat.APPLICATION_CBOR, MAP_CBOR.encodingPayloadToCbor(CRL_MANAGER.getPayload()));
+ } catch (CRLException e) {
+ Log.e(e.getMessage());
+ }
}
}
return iResponse;
}
+ /**
+ * Handles POST requests and sends back CRL data in response.
+ */
private IResponse handlePostRequest(IRequest request)
throws ServerException {
- HashMap<String, Object> payloadData = MAP_CBOR
+ 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);
IResponse response = MessageBuilder.createResponse(request, ResponseStatus.PRECONDITION_FAILED);
- if (thisUpdate != null || nextUpdate != null) {
- String encoding = (String) payloadData.get(Constants.CRL_ENCODING);
- byte[] crl = (byte[]) payloadData.get(Constants.CRL_DATA);
- if(encoding != null && crl != null && encoding.equals(CertificateConstants.BASE_64)) {
- if (encoding.equals(CertificateConstants.BASE_64)) {
- crl = org.bouncycastle.util.encoders.Base64.decode(crl);
- }
- CrlIssuer.update(crl);
- response = MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
- }
- Object reqSerialNumber = payloadData.get(Constants.REQ_SERIAL_NUMBER);
- if (reqSerialNumber != null) {
- Date thisUpdateDate = null;
- Date nextUpdateDate = null;
- boolean parseable = true;
- try {
- thisUpdateDate = DATE_FORMAT.parse(thisUpdate.toString());
- nextUpdateDate = DATE_FORMAT.parse(nextUpdate.toString());
- } catch (ParseException e) {
- Log.e(e.getMessage());
- parseable = false;
- }
- if(parseable) {
- CrlIssuer.update(thisUpdateDate, nextUpdateDate, reqSerialNumber.toString(), CertificateStorage.getRootCertificatePrivateKeyPair().getPrivateKey());
+ 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);
+ 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());
}
}
return response;
*/
package org.iotivity.cloud.accountserver.x509.cert;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMException;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCSException;
-import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
import org.iotivity.cloud.util.Log;
import java.io.IOException;
import java.security.PublicKey;
+import static org.bouncycastle.asn1.x500.style.BCStyle.CN;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.SECURITY_PROVIDER;
+/**
+ * Class is used for parsing CSR requests.
+ */
public class CSRParser {
- private static final String COUNTRY = "2.5.4.6";
-
- private static final String ORGANIZATION = "2.5.4.10";
-
- private static final String ORGANIZATION_UNIT = "2.5.4.11";
-
- private static final String COMMON_NAME = "2.5.4.3";
-
+ /**
+ * PKCS10CertificationRequest attribute.
+ */
private final PKCS10CertificationRequest mCsr;
/**
+ * Certificate subject.
+ */
+ private final X500Name subject;
+
+ /**
* Creates CSRParser instance with specified csrDer byte array.
*
* @param csrDer specified byte array.
*/
public CSRParser(byte[] csrDer) throws IOException {
mCsr = new PKCS10CertificationRequest(csrDer);
+ subject = mCsr.getSubject();
}
/**
* Returns public key
*/
- public PublicKey getPublicKey() throws PEMException {
- return new JcaPEMKeyConverter().setProvider(CertificateStorage.BC).getPublicKey(getPublicKeyInfo());
+ public PublicKey getPublicKey() {
+ PublicKey publicKey = null;
+ try {
+ publicKey = new JcaPEMKeyConverter().setProvider(SECURITY_PROVIDER).
+ getPublicKey(mCsr.getSubjectPublicKeyInfo());
+ } catch (PEMException e) {
+ Log.e(e.getMessage());
+ }
+ return publicKey;
}
/**
*
* @return true if signature is correct and false otherwise.
*/
- public boolean verify() {
+ public boolean isSignatureValid() {
boolean condition = false;
try {
condition = mCsr.isSignatureValid(new JcaContentVerifierProviderBuilder()
- .setProvider(CertificateStorage.BC).build(getPublicKeyInfo()));
+ .setProvider(SECURITY_PROVIDER).build(mCsr.getSubjectPublicKeyInfo()));
} catch (OperatorCreationException | PKCSException e) {
Log.e(e.getMessage());
}
}
/**
- * Returns Organization Unit from csr subject.
- */
- public String getOrganizationalUnit() {
- return getX500Field(ORGANIZATION_UNIT, mCsr.getSubject());
- }
-
- /**
- * Returns organization from csr subject.
- */
- public String getOrganizational() {
- return getX500Field(ORGANIZATION, mCsr.getSubject());
- }
-
- /**
- * Returns country from csr subject.
- */
- public String getCountry() {
- return getX500Field(COUNTRY, mCsr.getSubject());
- }
-
- /**
* Returns common name from csr subject.
*/
public String getCommonName() {
- return getX500Field(COMMON_NAME, mCsr.getSubject());
- }
+ return subject.getRDNs(CN)[0].getFirst().getValue().toString();
- /**
- * Returns public key information for this csr.
- */
- public SubjectPublicKeyInfo getPublicKeyInfo() {
- return mCsr.getSubjectPublicKeyInfo();
}
/**
- * Converts asn1.0 identifier ti string DATE_FORMAT.
- *
- * @param asn1ObjectIdentifier
- * @param x500Name
- * @return
+ * Returns subject as X500Name.
*/
- private String getX500Field(String asn1ObjectIdentifier, X500Name x500Name) {
- String result = null;
- RDN[] arRdns = x500Name.getRDNs(new ASN1ObjectIdentifier(asn1ObjectIdentifier));
- if (arRdns.length != 0) {
- result = arRdns[0].getFirst().getValue().toString();
- }
- return result;
+ public X500Name getSubject() {
+ return subject;
}
}
*/
package org.iotivity.cloud.accountserver.x509.cert;
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.X500NameBuilder;
-import org.bouncycastle.asn1.x500.style.IETFUtils;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.cert.CertIOException;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.ECNamedCurveTable;
-import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
import java.math.BigInteger;
-import java.security.*;
+import java.security.GeneralSecurityException;
+import java.security.PublicKey;
import java.security.cert.X509Certificate;
+import java.util.Calendar;
import java.util.Date;
-import static org.bouncycastle.asn1.x500.style.BCStyle.*;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
+/**
+ * Class is used for generating X509 certificate with specified in properties signature and ley algorithms.
+ */
public class CertificateBuilder {
- private String issuerName;
-
- private String subjectCN;
-
- private String subjectC;
-
- private String subjectO;
-
- private String subjectOU;
-
- private String subjectAltName;
-
- private Date notBefore;
-
- private Date notAfter;
-
- private PrivateKey privateKey;
-
+ /**
+ * SIGNER_BUILDER for building X509 certificates
+ */
+ public static final JcaContentSignerBuilder SIGNER_BUILDER = new JcaContentSignerBuilder(SIGNATURE_ALGORITHM)
+ .setProvider(SECURITY_PROVIDER);
+
+ /**
+ * Serial number of last issued certificate.
+ */
+ private static BigInteger SERIAL_NUMBER = new BigInteger(PROPERTIES.getProperty("serialNumber"));
+
+ /**
+ * Attribute for X500Name subject.
+ */
+ private X500Name subject;
+
+ /**
+ * Attribute for public key.
+ */
private PublicKey publicKey;
- private BigInteger serial;
-
- public static final String SIGNATURE_ALGORITHM = CertificateStorage.PROPERTIES.getProperty("signatureAlgorithm");
-
- private static final String CURVE = CertificateStorage.PROPERTIES.getProperty("ellipticCurve");
-
- private static final String KEY_GENERATOR_ALGORITHM = CertificateStorage.PROPERTIES.getProperty("keyGeneratorAlgorithm");
-
- private final X500NameBuilder subjectNameBld = new X500NameBuilder(INSTANCE);
-
- public CertificateBuilder(String subject, Date notBefore, Date notAfter, BigInteger serial) {
- init(subject, null, notBefore, notAfter, null, null, serial);
- }
-
- public CertificateBuilder(String subject, PublicKey pubKey, Date notBefore, Date notAfter,
- BigInteger serial, CertificatePrivateKeyPair root) {
- X500Name x500name = new X500Name(root.getX509Certificate().getSubjectX500Principal().getName());
- RDN cn = x500name.getRDNs(CN)[0];
- init(subject, IETFUtils.valueToString(cn.getFirst().getValue()), notBefore, notAfter, root.getPrivateKey(), pubKey, serial);
- }
-
- private void init(String subject, String issuer, Date notBefore, Date notAfter,
- PrivateKey privKey, PublicKey pubKey, BigInteger serial) {
- this.subjectCN = subject;
- this.issuerName = issuer;
- this.notBefore = notBefore;
- this.notAfter = notAfter;
- this.privateKey = privKey;
- this.publicKey = pubKey;
- this.serial = serial;
- subjectNameBld.addRDN(CN, subjectCN);
+ /**
+ * Attribute for certificate extension.
+ */
+ private CertificateExtension extension;
+
+ /**
+ * Constructs certificate builder with specified subject
+ * public key and certificate extension.
+ */
+ public CertificateBuilder(X500Name subject,
+ PublicKey publicKey, CertificateExtension extension) {
+ this.subject = subject;
+ this.publicKey = publicKey;
+ this.extension = extension;
}
- public void setSubjectC(String subjectC) {
- this.subjectC = subjectC;
- subjectNameBld.addRDN(C, subjectC);
+ /**
+ * Builds X509Certificate with default root key.
+ */
+ public X509Certificate build() throws CertIOException, GeneralSecurityException, OperatorCreationException {
+ X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
+ CA_ISSUER,
+ getNextSerialNumber(), getNotBeforeDate(), getNotAfterDate(), subject, publicKey);
+ certGen.addExtension(extension.getOid(), extension.isCritical(),
+ extension.getValue());
+ return new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER).
+ getCertificate(certGen.build(
+ SIGNER_BUILDER.build(CertificateStorage.ROOT_PRIVATE_KEY)));
}
- public void setSubjectO(String subjectO) {
- this.subjectO = subjectO;
- subjectNameBld.addRDN(O, subjectO);
+ /**
+ * Returns next serial number.
+ */
+ private static BigInteger getNextSerialNumber() {
+ SERIAL_NUMBER = SERIAL_NUMBER.add(BigInteger.ONE);
+ set("serialNumber", SERIAL_NUMBER.toString());
+ return SERIAL_NUMBER;
}
- public void setSubjectOU(String subjectOU) {
- this.subjectOU = subjectOU;
- subjectNameBld.addRDN(OU, subjectOU);
+ /**
+ * Returns date not before.
+ */
+ private Date getNotBeforeDate() {
+ return Calendar.getInstance().getTime();
}
- public void setSubjectAltName(String subjectAltName) {
- this.subjectAltName = subjectAltName;
+ /**
+ * Returns date not after.
+ */
+ private Date getNotAfterDate() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) +
+ Integer.parseInt(NOT_AFTER_INTERVAL));
+ return calendar.getTime();
}
- public CertificatePrivateKeyPair build()
- throws GeneralSecurityException, OperatorCreationException, CertIOException {
- if (privateKey == null && publicKey == null) {
- ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(CURVE);
- KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, CertificateStorage.BC);
- g.initialize(ecSpec, new SecureRandom());
- KeyPair pair = g.generateKeyPair();
- privateKey = pair.getPrivate();
- publicKey = pair.getPublic();
- issuerName = subjectCN;
- }
- X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
- new X500NameBuilder(INSTANCE).addRDN(CN, issuerName).build(),
- serial, notBefore, notAfter, subjectNameBld.build(), publicKey);
-
- if (subjectAltName != null) {
- ASN1Encodable[] subjectAlternativeNames = new ASN1Encodable[]
- {
- new GeneralName(GeneralName.dNSName, subjectAltName)
- };
- DERSequence subjectAlternativeNamesExtension = new DERSequence(subjectAlternativeNames);
- certGen.addExtension(Extension.subjectAlternativeName, false,
- subjectAlternativeNamesExtension);
- }
- X509Certificate cert = new JcaX509CertificateConverter().setProvider(CertificateStorage.BC).
- getCertificate(certGen.build(
- new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).setProvider(CertificateStorage.BC).build(privateKey)));
-
- return new CertificatePrivateKeyPair(cert, privateKey);
- }
}
\ No newline at end of file
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * // http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.x509.cert;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * Class for representing certificate extension.
+ */
+public class CertificateExtension {
+
+ /**
+ * Attribute for ASN1 object identifier.
+ */
+ private final ASN1ObjectIdentifier oid;
+
+ /**
+ * Attribute checks critical or non critical type of extension.
+ */
+ private final boolean isCritical;
+
+ /**
+ * Attribute stores ASN1 Encodable value
+ */
+ private final ASN1Encodable value;
+
+ /**
+ * Constructs certificate extension with specified oid, isCritical, value parameters.
+ */
+ public CertificateExtension(ASN1ObjectIdentifier oid, boolean isCritical, ASN1Encodable value) {
+ this.oid = oid;
+ this.isCritical = isCritical;
+ this.value = value;
+ }
+
+ /**
+ * Returns attribute value for oid
+ */
+ ASN1ObjectIdentifier getOid() {
+ return oid;
+ }
+
+ /**
+ * Returns isCritical attribute value.
+ */
+ boolean isCritical() {
+ return isCritical;
+ }
+
+ /**
+ * Returns ASN1Encodable attribute value.
+ *
+ * @return
+ */
+ ASN1Encodable getValue() {
+ return value;
+ }
+}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // Copyright 2016 Samsung Electronics All Rights Reserved.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- * //
- * // Licensed under the Apache License, Version 2.0 (the "License");
- * // you may not use this file except in compliance with the License.
- * // You may obtain a copy of the License at
- * //
- * // http://www.apache.org/licenses/LICENSE-2.0
- * //
- * // Unless required by applicable law or agreed to in writing, software
- * // distributed under the License is distributed on an "AS IS" BASIS,
- * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * // See the License for the specific language governing permissions and
- * // limitations under the License.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.x509.cert;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-public class CertificatePrivateKeyPair {
-
- private final X509Certificate x509Certificate;
-
- private final PrivateKey privateKey;
-
- /**
- * Constructs new CertificatePrivateKeyPair with help of X509Certificate and PrivateKey instances.
- * @param x509Certificate specified certificate
- * @param privateKey specified private key.
- */
- public CertificatePrivateKeyPair(X509Certificate x509Certificate, PrivateKey privateKey) {
- this.x509Certificate = x509Certificate;
- this.privateKey = privateKey;
- }
-
- /**
- * Returns private key.
- */
- public PrivateKey getPrivateKey() {
- return privateKey;
- }
-
- /**
- * Returns certificate.
- */
- public X509Certificate getX509Certificate() {
- return x509Certificate;
- }
-}
-
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * // http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+package org.iotivity.cloud.accountserver.x509.cert;
+
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.X500NameBuilder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import static org.bouncycastle.asn1.x500.style.BCStyle.*;
+import static org.iotivity.cloud.accountserver.Constants.*;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.ACCOUNT_DB_MANAGER;
+
+/**
+ * Utility class is for getting X500Name from common name, country, organization and organization unit name
+ */
+public final class Utility {
+
+ /**
+ * Forbid creation of new Utility object. This class is final
+ * and non-instantiable
+ */
+ private Utility() {
+ throw new AssertionError();
+ }
+
+ /**
+ * Returns X500Name contructed with help of specified parameters commonName, country, organizational
+ * and organizationUnit
+ */
+ public static X500Name getName(String commonName, String country, String organizational, String organizationUnit) {
+ X500NameBuilder nameBuilder = new X500NameBuilder(INSTANCE);
+ nameBuilder.addRDN(CN, commonName);
+ nameBuilder.addRDN(C, country);
+ nameBuilder.addRDN(O, organizational);
+ nameBuilder.addRDN(OU, organizationUnit);
+ return nameBuilder.build();
+ }
+
+ /**
+ * Retrieves user id from Token Table by specified deviceId.
+ */
+ public static String getUserID(String deviceId) {
+ HashMap<String, Object> condition = new HashMap<>();
+ condition.put(KEYFIELD_DID, deviceId);
+ ArrayList<HashMap<String, Object>> recordList = ACCOUNT_DB_MANAGER.selectRecord(TOKEN_TABLE, condition);
+ Iterator<HashMap<String, Object>> iterator = recordList.iterator();
+ String result = null;
+ if (iterator.hasNext()) {
+ result = iterator.next().get(KEYFIELD_UUID).toString();
+ }
+ return result;
+ }
+
+
+}
*/
package org.iotivity.cloud.accountserver.x509.crl;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.cert.X509CRLEntryHolder;
+
import org.bouncycastle.cert.X509v2CRLBuilder;
-import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
import org.iotivity.cloud.accountserver.x509.cert.CertificateBuilder;
-import org.iotivity.cloud.util.Log;
import java.io.IOException;
import java.math.BigInteger;
-import java.security.PrivateKey;
-import java.text.ParseException;
+import java.security.cert.X509CRLEntry;
import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
-import static org.iotivity.cloud.accountserver.x509.crl.CrlParser.DATE_FORMAT;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.CA_ISSUER;
+/**
+ * Class is used for generating CRL with specified parameters.
+ */
public final class CrlIssuer {
+ /**
+ * Creates static final reference for CRL issuer.
+ */
+ public static final CrlIssuer CRL_ISSUER = new CrlIssuer();
+ /**
+ * Creates new instance of CRL issuer.
+ */
private CrlIssuer() {
- throw new AssertionError();
}
- public static byte[] generate(Date thisUpdate, Date nextUpdate,
- PrivateKey key, BigInteger[] serialNumbers, Collection<X509CRLEntryHolder> certs, String issuer) {
- X500Name issuerDN = new X500Name(issuer);
- X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(issuerDN,
+ /**
+ * Generates new CRL with specified this update, next update, certs and serial numbers list.
+ */
+ 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);
- if (nextUpdate != null) {
- crlBuilder.setNextUpdate(nextUpdate);
- }
- for (X509CRLEntryHolder crlItem : certs) {
- crlBuilder.addCRLEntry(crlItem.getSerialNumber(), crlItem.getRevocationDate(), 0);
+ crlBuilder.setNextUpdate(nextUpdate);
+ if (certs != null) {
+ for (X509CRLEntry entryHolder : certs) {
+ crlBuilder.addCRLEntry(entryHolder.getSerialNumber(), entryHolder.getRevocationDate(), 0);
+ }
}
- for (BigInteger serialNumber : serialNumbers) {
- crlBuilder.addCRLEntry(serialNumber, new Date(), 0);
+ for (String serialNumber : serialNumbers) {
+ crlBuilder.addCRLEntry(new BigInteger(serialNumber), new Date(), 0);
}
- byte[] data = null;
- try {
- ContentSigner signer = new JcaContentSignerBuilder(CertificateBuilder.SIGNATURE_ALGORITHM)
- .setProvider(CertificateStorage.BC).build(key);
- data = crlBuilder.build(signer).getEncoded();
- CrlStore.save(data);
- } catch (OperatorCreationException | IOException e) {
- Log.e(e.getMessage());
- }
- return data;
- }
-
- public static byte[] generate(String issuerName, Date thisUpdate, Date nextUpdate,
- PrivateKey key) {
- return generate(thisUpdate, nextUpdate, key, new BigInteger[]{}, Collections.EMPTY_LIST, issuerName);
-
- }
-
- public static void update(byte[] crl) {
- CrlStore.save(crl);
+ crl = crlBuilder.build(CertificateBuilder.SIGNER_BUILDER.
+ build(CertificateStorage.ROOT_PRIVATE_KEY)).getEncoded();
+ return crl;
}
-
- public static void revokeCertificate(BigInteger serialNumber, PrivateKey key) {
- byte[] data = CrlStore.load();
- CrlParser parser = new CrlParser(data);
- Collection<X509CRLEntryHolder> certificates = parser.getCerts();
- X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(new X500Name(parser.getIssuer()),
- parser.getThisUpdate());
- crlBuilder.setNextUpdate(parser.getNextUpdate());
- for (X509CRLEntryHolder entryHolder : certificates) {
- crlBuilder.addCRLEntry(entryHolder.getSerialNumber(), entryHolder.getRevocationDate(), 0);
- }
- crlBuilder.addCRLEntry(serialNumber, new Date(), 0);
- try {
- ContentSigner signer = new JcaContentSignerBuilder(CertificateBuilder.SIGNATURE_ALGORITHM)
- .setProvider(CertificateStorage.BC).build(key);
- CrlStore.save(crlBuilder.build(signer).getEncoded());
- } catch (OperatorCreationException | IOException e) {
- Log.e(e.getMessage());
- }
- }
-
- public static void update(Date thisUpdate, Date nextUpdate,
- String serialNumber, PrivateKey key) {
- String[] serials = serialNumber.split(",");
- BigInteger[] serialNumbers = new BigInteger[serials.length];
- for (int i = 0; i < serials.length; i++) {
- serialNumbers[i] = new BigInteger(serials[i]);
- }
- CrlParser crlParser = new CrlParser(CrlStore.load());
- generate(thisUpdate, nextUpdate, key, serialNumbers, crlParser.getCerts(), crlParser.getIssuer());
- }
-}
-
+}
\ No newline at end of file
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // Copyright 2016 Samsung Electronics All Rights Reserved.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- * //
- * // Licensed under the Apache License, Version 2.0 (the "License");
- * // you may not use this file except in compliance with the License.
- * // You may obtain a copy of the License at
- * //
- * // http://www.apache.org/licenses/LICENSE-2.0
- * //
- * // Unless required by applicable law or agreed to in writing, software
- * // distributed under the License is distributed on an "AS IS" BASIS,
- * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * // See the License for the specific language governing permissions and
- * // limitations under the License.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.x509.crl;
-
-import org.bouncycastle.cert.X509CRLEntryHolder;
-import org.bouncycastle.cert.X509CRLHolder;
-import org.iotivity.cloud.util.Log;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-
-public class CrlParser {
-
- private X509CRLHolder mCrl;
-
- public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
-
-
- public CrlParser(byte[] crl) {
- try {
- mCrl = new X509CRLHolder(crl);
- } catch (IOException e) {
- Log.e(e.getMessage());
- }
- }
-
- public Date getThisUpdate() {
- return mCrl.toASN1Structure().getThisUpdate().getDate();
- }
-
- public Date getNextUpdate() {
- return mCrl.toASN1Structure().getNextUpdate().getDate();
- }
-
- public String getIssuer() {
- return mCrl.getIssuer().toString();
- }
-
- @SuppressWarnings("unchecked")
- public Collection<X509CRLEntryHolder> getCerts() {
- return mCrl.getRevokedCertificates();
- }
-}
+++ /dev/null
-/*
- * //******************************************************************
- * //
- * // Copyright 2016 Samsung Electronics All Rights Reserved.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- * //
- * // Licensed under the Apache License, Version 2.0 (the "License");
- * // you may not use this file except in compliance with the License.
- * // You may obtain a copy of the License at
- * //
- * // http://www.apache.org/licenses/LICENSE-2.0
- * //
- * // Unless required by applicable law or agreed to in writing, software
- * // distributed under the License is distributed on an "AS IS" BASIS,
- * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * // See the License for the specific language governing permissions and
- * // limitations under the License.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.x509.crl;
-
-import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
-import org.iotivity.cloud.util.Log;
-
-import java.io.*;
-import java.text.MessageFormat;
-import java.util.Date;
-
-public final class CrlStore {
-
- private CrlStore() {
- throw new AssertionError();
- }
-
- private static final File CRL_FILE = new File(MessageFormat.format(CertificateStorage.PROPERTIES.getProperty("crlLocation"), File.separator));
-
- public static void save(byte[] crl) {
- try {
- FileOutputStream out = new FileOutputStream(CRL_FILE);
- out.write(crl);
- out.close();
- } catch (IOException e) {
- Log.e(e.getMessage());
- }
- }
-
- public static byte[] load() {
- try {
- InputStream f = new FileInputStream(CRL_FILE);
- int size = f.available();
- byte data[] = new byte[size];
- if (f.read(data) != data.length) {
- System.err.println("couldn't read crl");
- }
- f.close();
- return data;
-
- } catch (java.io.IOException e) {
- Log.e(e.getMessage());
- }
- return null;
- }
-
- public static boolean checkLastUpdate(Date lastUpdate) {
- boolean result = false;
- try {
- if (CRL_FILE.isFile()) {
- Date current = new Date(CRL_FILE.lastModified());
- result = current.after(lastUpdate);
- }
- } catch (Exception e) {
- Log.e(e.getMessage());
- }
- return result;
- }
-}
\ No newline at end of file
private static final String GROUP_URI = Constants.GROUP_FULL_URI;
private static final String DEVICE_ID = "B371C481-38E6-4D47-8320-7688D8A5B58C";
private String mAuthProvider = "Github";
- private String mAuthCode = "c2820e39232088dca7d4";
+ private String mAuthCode = "00a93f698b47980b2d77";
private CoapDevice mMockDevice = mock(
CoapDevice.class);
private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
import org.bouncycastle.util.encoders.Base64;
import org.iotivity.cloud.accountserver.Constants;
-import org.iotivity.cloud.accountserver.resources.account.AccountResource;
+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;
import org.iotivity.cloud.base.device.CoapDevice;
import org.iotivity.cloud.base.protocols.IRequest;
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;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
+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.util.concurrent.CountDownLatch;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
+import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
public class CertificateResourceTest {
- private static final String COMMON_NAME = "OU=OCF Root CA, O=Samsung, C=US, CN=uuid:B371C481-38E6-4D47-8320-7688D8A5B58C";
+ private static final String COMMON_NAME = "OU=OCF Device CA, O=Samsung, C=KR, CN=uuid: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 CoapDevice mMockDevice = mock(CoapDevice.class);
+
private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
+
private IResponse mResponse = null;
+
private CountDownLatch mLatch = new CountDownLatch(
1);
- private CertificateResource certificateResource = new CertificateResource();
+
+ 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);
+ certificateTable.setUuid("uuid:" + DEVICE_ID);
+ AccountDBManager.getInstance().insertRecord(Constants.TOKEN_TABLE,
+ castingManager.convertObjectToMap(certificateTable));
+ }
+
+ @AfterClass
+ public static void after() {
+ KEYSTORE_FILE.delete();
+ }
+
+ @BeforeClass
+ public static void setUpBefore() {
+ createToken();
+ }
+
+ /**
+ * DERSequence othernameSequence = new DERSequence(new ASN1Encodable[]{
+ * new ASN1ObjectIdentifier("1.3.6.1.5.5.7.8.5"), new DERTaggedObject(true, 0, new DERUTF8String(subjectAltName))});
+ * GeneralName othernameGN = new GeneralName(GeneralName.otherName, othernameSequence);
+ * ASN1Encodable[] subjectAlternativeNames = new ASN1Encodable[]
+ * {
+ * othernameGN
+ * <p>
+ * <p>
+ * };
+ * DERSequence subjectAlternativeNamesExtension = new DERSequence(othernameGN);
+ * return buildOne(Extension.subjectAlternativeName, true, subjectAlternativeNamesExtension, issuerNameBld.build());
+ */
+ @Test
+ public void testLoad() {
+ try {
+ Method m = CertificateStorage.class.getDeclaredMethod("load");
+ m.setAccessible(true);
+ m.invoke(null);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+
@Before
public void setUp() throws Exception {
csr = GenerateCSR.generatePKCS10(COMMON_NAME, false);
throws Throwable {
Object[] args = invocation.getArguments();
CoapResponse resp = (CoapResponse) args[0];
- System.out
- .println("\t----payload : " + resp.getPayloadString());
-
- System.out
- .println("\t----responsestatus : " + resp.getStatus());
mResponse = resp;
}).when(mMockDevice).sendResponse(Mockito.anyObject());
}
+ @Test(expected = AssertionError.class)
+ public void testErrorConstruction() {
+ Constructor<CertificateStorage> constructor;
+ try {
+ constructor = CertificateStorage.class.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ constructor.newInstance();
+ } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ throw new AssertionError();
+ }
+
+ }
+
+ @Test(expected = AssertionError.class)
+ public void testErrorConstructionUtility() {
+ Constructor<Utility> constructor;
+ try {
+ constructor = Utility.class.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ constructor.newInstance();
+ } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ throw new AssertionError();
+ }
+ }
+
+ @Test(expected = AssertionError.class)
+ public void testErrorConstructionCertificateConstants() {
+ Constructor<CertificateConstants> constructor;
+ try {
+ constructor = CertificateConstants.class.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ constructor.newInstance();
+ } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ throw new AssertionError();
+ }
+
+ }
+
+ /**
+ * DERUTF8String derDomainName = new DERUTF8String("hello.world");
+ * DERTaggedObject derTaggedDomainName = new DERTaggedObject(0, derDomainName);
+ * DLSequence otherName = new DLSequence(new ASN1Encodable[]{new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.3"), derTaggedDomainName});
+ * GeneralNames generalNames = new GeneralNames(new GeneralName(GeneralName.otherName, otherName));
+ *
+ * @throws Exception
+ */
+
@Test
public void testCSRIssueDER() throws Exception {
getTestMethodName();
Map<String, Object> payloadData = mCbor
.parsePayloadFromCbor(mResponse.getPayload(), HashMap.class);
assertTrue(hashmapCheck(mResponse, Constants.REQ_DEVICE_ID));
- assertTrue(hashmapCheck(mResponse, Constants.CERT_ENCODING));
- assertTrue(hashmapCheck(mResponse, Constants.CERT_DATA));
- assertTrue(hashmapCheck(mResponse, Constants.CERTCHAIN_ENCODING));
- assertTrue(hashmapCheck(mResponse, Constants.CERTCHAIN_DATA));
-
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- InputStream in = new ByteArrayInputStream((byte[]) payloadData.get(Constants.CERT_DATA));
- X509Certificate cert = (X509Certificate) certFactory.generateCertificate(in);
-
-
- assertEquals(COMMON_NAME, cert.getSubjectDN().getName());
- assertEquals(cert.getPublicKey(), GenerateCSR.getPublicKey());
- assertEquals("CN="+CertificateStorage.SUBJECT_NAME, cert.getIssuerDN().getName());
- System.out.println(cert);
+ assertTrue(hashmapCheck(mResponse, Constants.CERT));
+ assertTrue(hashmapCheck(mResponse, Constants.CERT_CHAIN));
+ Map<String, Object> certMap = (Map<String, Object>) payloadData.get(Constants.CERT);
+ InputStream in = new ByteArrayInputStream((byte[]) certMap.get(Constants.DATA));
+ X509Certificate personaleCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
+ personaleCert.verify(CertificateStorage.ROOT_CERTIFICATE.getPublicKey());
+ assertEquals(COMMON_NAME, personaleCert.getSubjectDN().getName());
+ String encoding = certMap.get(Constants.ENCODING).toString();
+ assertEquals(CertificateConstants.DER, encoding);
+ assertEquals(personaleCert.getPublicKey(), GenerateCSR.getPublicKey());
+ certMap = (Map<String, Object>) payloadData.get(Constants.CERT_CHAIN);
+ encoding = certMap.get(Constants.ENCODING).toString();
+ assertEquals(CertificateConstants.DER, encoding);
+ in = new ByteArrayInputStream((byte[]) certMap.get(Constants.DATA));
+ X509Certificate caCert = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(in);
+ assertEquals(caCert, CertificateStorage.ROOT_CERTIFICATE);
assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+ }
+ @Test
+ public void testCSRIssueDERFailed() throws Exception {
+ getTestMethodName();
+ IRequest request = csrRequestFailed(DEVICE_ID, RequestMethod.POST);
+ certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.BAD_REQUEST));
}
@Test
IRequest request = csrRequest(DEVICE_ID, CertificateConstants.DER, csr, RequestMethod.POST, true);
certificateResource.onDefaultRequestReceived(mMockDevice, request);
assertTrue(methodCheck(mResponse, ResponseStatus.BAD_REQUEST));
-
}
+ Map<String, Object> payloadData;
+
+ Map<String, Object> crlMap;
+
+ byte[] data;
+
+ X509CRL crlX509;
+
@Test
- public void testReIssueBase64() {
+ 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() {
assertTrue(methodCheck(mResponse, ResponseStatus.METHOD_NOT_ALLOWED));
}
-
-
@Test
public void testBadRequest() {
IRequest request = csrRequest(DEVICE_ID, CertificateConstants.DER, csr, RequestMethod.POST, false);
System.out.println("\t---Test Name : " + currentStack.getMethodName());
}
+ private IRequest csrRequestFailed(String deviceId, RequestMethod method) {
+ IRequest request;
+ HashMap<String, Object> payloadData = new HashMap<>();
+ payloadData.put(Constants.REQ_DEVICE_ID, deviceId);
+ payloadData.put("csr", "csr");
+ request = MessageBuilder.createRequest(method, CERTIFICATE_URI,
+ null, ContentFormat.APPLICATION_CBOR,
+ mCbor.encodingPayloadToCbor(payloadData));
+ return request;
+ }
+
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);
+ CSR csr = new CSR();
if (isEncoded) {
- payloadData.put(Constants.CSR_ENCODING, encoding);
+ csr.setEncoding(encoding);
+ csr.setData(data);
+ payloadData.put("csr", csr);
}
- payloadData.put(Constants.CSR_DATA, data);
request = MessageBuilder.createRequest(method, CERTIFICATE_URI,
null, ContentFormat.APPLICATION_CBOR,
mCbor.encodingPayloadToCbor(payloadData));
return request;
}
+ private static class CSR {
+ String encoding;
+
+ byte[] data;
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+
+ @Override
+ public String toString() {
+ return "CSR{" +
+ "encoding='" + encoding + '\'' +
+ ", data=" + Arrays.toString(data) +
+ '}';
+ }
+ }
+
private boolean methodCheck(IResponse response,
ResponseStatus responseStatus) {
if (responseStatus == response.getStatus())
return false;
}
-
private boolean hashmapCheck(IResponse response, String propertyName) {
HashMap<String, Object> payloadData = mCbor
.parsePayloadFromCbor(response.getPayload(), HashMap.class);
package org.iotivity.cloud.accountserver.resources.account.credprov.cert;
-import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
-import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateStorage;
+import org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants;
import javax.security.auth.x500.X500Principal;
import java.security.*;
-import static org.bouncycastle.asn1.x500.style.BCStyle.INSTANCE;
-
-/**
- * This class generates PKCS10 certificate signing request
- *
- * @author Pankaj@JournalDev.com
- * @version 1.0
- */
public class GenerateCSR {
- public static final String SIGNATURE_ALGORITHM = CertificateStorage.PROPERTIES.getProperty("signatureAlgorithm");
+ public static final String SIGNATURE_ALGORITHM = CertificateConstants.PROPERTIES.getProperty("signatureAlgorithm");
- private static final String CURVE = CertificateStorage.PROPERTIES.getProperty("ellipticCurve");
+ private static final String CURVE = CertificateConstants.PROPERTIES.getProperty("ellipticCurve");
- private static final String KEY_GENERATOR_ALGORITHM = CertificateStorage.PROPERTIES.getProperty("keyGeneratorAlgorithm");
+ private static final String KEY_GENERATOR_ALGORITHM = CertificateConstants.PROPERTIES.getProperty("keyGeneratorAlgorithm");
- private final X500NameBuilder subjectNameBld = new X500NameBuilder(INSTANCE);
private static PublicKey publicKey = null;
private static PrivateKey privateKey = null;
private static PublicKey publicKey1 = null;
*/
public static byte[] generatePKCS10(String commonName, boolean falseKey) throws Exception {
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(CURVE);
- KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, CertificateStorage.BC);
+ KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM, CertificateConstants.SECURITY_PROVIDER);
g.initialize(ecSpec, new SecureRandom());
KeyPair pair = g.generateKeyPair();
privateKey = pair.getPrivate();
publicKey = pair.getPublic();
-
-
pair = g.generateKeyPair();
privateKey1 = pair.getPrivate();
publicKey1 = pair.getPublic();
return publicKey;
}
- public static PrivateKey getPrivateKey() {
- return privateKey;
- }
-
+
}
\ No newline at end of file
package org.iotivity.cloud.accountserver.resources.account.credprov.crl;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+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.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.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.device.CoapDevice;
import org.iotivity.cloud.base.protocols.IRequest;
import org.iotivity.cloud.base.protocols.IResponse;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.security.PublicKey;
import java.security.Security;
-import java.util.HashMap;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.text.ParseException;
+import java.util.*;
import java.util.concurrent.CountDownLatch;
-import static org.junit.Assert.assertTrue;
+import static org.iotivity.cloud.accountserver.resources.credprov.cert.CertificateConstants.*;
+import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
public class CrlResourceTest {
private CoapDevice mMockDevice = mock(CoapDevice.class);
- private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
+ private Cbor<Map<String, Object>> mCbor = new Cbor<>();
private IResponse mResponse = null;
private CountDownLatch mLatch = new CountDownLatch(
1);
- private CrlResource certificateResource = new CrlResource();
- private static final String CRL_URI = "/oic/credprov/crl";
- private static final String CRL_URI_QUERY = "lu=20160726210000";
+ public static final String[] FOR_SERIAL_NUMBER = {Constants.REQ_THIS_UPDATE, Constants.REQ_NEXT_UPDATE, Constants.REQ_SERIAL_NUMBER};
+ public static final String CRL_URI = Constants.PREFIX_OIC + "/" + Constants.CREDPROV_URI + "/" +
+ Constants.REQ_CRL;
+ public static final String CRL_URI_QUERY = "lu=20160726210000";
+ 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();
+
+ private static TypeCastingManager<CRLTable> castingManager = new TypeCastingManager<>();
static {
Security.insertProviderAt(new BouncyCastleProvider(), 0);
+ new CertificateResource();
}
+ /**
+ * Serial number of last issued certificate.
+ */
+ private static BigInteger SERIAL_NUMBER = new BigInteger(PROPERTIES.getProperty("serialNumber"));
+
+ Map<String, Object> payloadData;
+
+ Map<String, Object> crlMap;
+
+ byte[] data;
+
+ X509CRL crlX509;
+
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- // callback mock
Mockito.doAnswer(new Answer<Object>() {
@Override
public CoapResponse answer(InvocationOnMock invocation)
throws Throwable {
Object[] args = invocation.getArguments();
CoapResponse resp = (CoapResponse) args[0];
- System.out
- .println("\t----payload : " + resp.getPayloadString());
-
- System.out
- .println("\t----responsestatus : " + resp.getStatus());
mResponse = resp;
-
+ 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);
+ CertificateFactory factory = CertificateFactory.getInstance("X509");
+ crlX509 = (X509CRL) factory.generateCRL(new ByteArrayInputStream(data));
+ }
mLatch.countDown();
return null;
}).when(mMockDevice).sendResponse(Mockito.anyObject());
}
+
+ CRLTable getCRLTime() {
+
+ List<HashMap<String, Object>> listMap = AccountDBManager.getInstance().selectRecord(
+ Constants.CRL_TABLE, new HashMap<>());
+ if (!listMap.isEmpty()) {
+ return castingManager
+ .convertMaptoObject(
+ listMap.get(0),
+ new CRLTable());
+ } else {
+ return null;
+ }
+ }
+
+ private CrlResource crlResource = new CrlResource();
+
+ /**
+ * Returns next serial number.
+ */
+ private static BigInteger getNextSerialNumber() {
+ SERIAL_NUMBER = SERIAL_NUMBER.add(BigInteger.ONE);
+ set("serialNumber", SERIAL_NUMBER.toString());
+ return SERIAL_NUMBER;
+ }
+
@Test
- public void testCrlGet() throws Exception {
+ public void testCrlGetContent() throws Exception {
getTestMethodName();
IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ hashmapCheck(mResponse, Constants.ENCODING);
+ hashmapCheck(mResponse, Constants.DATA);
+ assertEquals(DER, crlMap.get(Constants.ENCODING));
+ assertNotNull(data);
+ crlX509.verify(key);
}
@Test
- public void testCrlGetNotFound() throws Exception {
+ public void testCrlGetNotFoundLastUpdateConditionFalse() throws Exception {
getTestMethodName();
- IRequest request = crlRequest(RequestMethod.GET, null,null);
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY_CONDITION_FALSE);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
assertTrue(methodCheck(mResponse, ResponseStatus.NOT_FOUND));
}
@Test
- public void testCrlGetBadQuery() throws Exception {
+ public void testCrlGetNotFoundNullPointer() throws Exception {
getTestMethodName();
- IRequest request = crlRequest(RequestMethod.GET, CRL_URI,"lu=1231212asdzfg4123123123123123");
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, null);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
assertTrue(methodCheck(mResponse, ResponseStatus.NOT_FOUND));
}
@Test
- public void testCrlPost() throws Exception {
+ public void testCrlGetNotFoundParseError() throws Exception {
+ getTestMethodName();
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY_PARSE_ERROR);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.NOT_FOUND));
+ }
+
+ @Test(expected = InvocationTargetException.class)
+ public void testNullX509CRL() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ Method m = null;
+ m = CrlManager.class.getDeclaredMethod("setX509CRL", byte[].class);
+ m.setAccessible(true);
+ System.out.println(m);
+ m.invoke(CrlManager.CRL_MANAGER, "Hello".getBytes());
+ }
+
+ @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();
String thisUpdate = "20160823000000";
String nextUpdate = "20161123000000";
- String serialNUmber = "123456";
- IRequest request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ byte[] crl = CrlIssuer.CRL_ISSUER.generate(DATE_FORMAT.parse(thisUpdate),
+ DATE_FORMAT.parse(nextUpdate), Collections.emptyList());
+ IRequest request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, Base64.encode(Arrays.copyOf(crl, crl.length - 2)), BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ crl = new byte[8];
+ request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, Base64.encode(crl), BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ crl = new byte[8];
+ request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, crl, BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ }
+
+ @Test
+ public void testCrlPostSerialNumberFailedData() throws Exception {
+ getTestMethodName();
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ String thisUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getThisUpdate());
+ String nextUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getNextUpdate());
+ String next = getNextSerialNumber().subtract(BigInteger.valueOf(3l)).toString();
+ String[] serialNUmber = new String[]{"123456", "1234", "12312", next};
+ request = crlRequestFailedCRL(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ }
+
+ @Test
+ public void testCrlPostSerialNumber() throws Exception {
+ getTestMethodName();
+ testCrlPostEncodingBase64();
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ String thisUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getThisUpdate());
+ String nextUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getNextUpdate());
+ String next = getNextSerialNumber().subtract(BigInteger.valueOf(3l)).toString();
+ String nextNext = getNextSerialNumber().subtract(BigInteger.valueOf(3l)).toString();
+
+ String[] serialNUmber = new String[]{"123456", "1234", "12312", next, nextNext};
+ request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+ serialNUmber = new String[]{"12345612312", "12341231", "12312231"};
+ request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+ serialNUmber = new String[]{"12345612312", "12341231", "12312231", "123456", "1234", "12312", next, nextNext};
+ request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ assertEquals(DER, crlMap.get(Constants.ENCODING));
+ Set<? extends X509CRLEntry> entries = crlX509.getRevokedCertificates();
+ Iterator<? extends X509CRLEntry> iterator = entries.iterator();
+
+ while (iterator.hasNext()) {
+ assertTrue(Arrays.asList(serialNUmber).contains(iterator.next().getSerialNumber().toString()));
+ }
+ CRLTable table = getCRLTime();
+ assertEquals(DATE_FORMAT.format(table.getThisUpdate()), thisUpdate);
+
+ }
+
+ @Test
+ public void testSerialNumberNull() {
+ IRequest request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ String thisUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getThisUpdate());
+ String nextUpdate = CertificateConstants.DATE_FORMAT.format(crlX509.getNextUpdate());
+ String[] serialNUmber = null;
+ request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
}
@Test
getTestMethodName();
String thisUpdate = "l;dkfjg;ls";
String nextUpdate = "sdfgsdfg";
- String serialNUmber = "123456";
+ String[] serialNUmber = new String[]{"123456"};
IRequest request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
}
@Test
- public void testCrlPostPreconditionFailed() throws Exception {
+ public void testCrlPostNullDate() throws Exception {
getTestMethodName();
String thisUpdate = null;
String nextUpdate = null;
- String serialNUmber = "123456";
+ String[] serialNUmber = new String[]{"123456"};
IRequest request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, serialNUmber);
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
}
+ @Test
+ public void testCrlPostEncodingBase64() throws Exception {
+ getTestMethodName();
+ String thisUpdate = "20160831000000";
+ String nextUpdate = "20161123000000";
+ byte[] crl = CrlIssuer.CRL_ISSUER.generate(DATE_FORMAT.parse(thisUpdate),
+ DATE_FORMAT.parse(nextUpdate), Collections.emptyList());
+ IRequest request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, Base64.encode(crl), BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+ request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ assertEquals(DER, crlMap.get(Constants.ENCODING));
+ }
+
+ @Test
+ public void testCrlPostEncodingBase64FailedCRL() throws Exception {
+ getTestMethodName();
+ String thisUpdate = "20160831000000";
+ String nextUpdate = "20161123000000";
+ IRequest request = crlRequestFailedCRL(RequestMethod.POST, thisUpdate, nextUpdate, BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ }
+
+ @Test
+ public void testCrlPostEncodingBase64FailedDate() throws Exception {
+ getTestMethodName();
+ String thisUpdate = "20160831000000";
+ String nextUpdate = "20161123000000";
+ byte[] crl = CrlIssuer.CRL_ISSUER.generate(DATE_FORMAT.parse(thisUpdate),
+ DATE_FORMAT.parse(nextUpdate), Collections.emptyList());
+ IRequest request = crlRequestFailedDate(RequestMethod.POST, thisUpdate, nextUpdate, BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ }
+
+ @Test
+ public void testCrlPostEncodingBase64FailedPayload() throws Exception {
+ getTestMethodName();
+ String thisUpdate = "20160831000000";
+ String nextUpdate = "20161123000000";
+ byte[] crl = CrlIssuer.CRL_ISSUER.generate(DATE_FORMAT.parse(thisUpdate),
+ DATE_FORMAT.parse(nextUpdate), Collections.emptyList());
+ IRequest request = crlRequestFailedPayload(RequestMethod.POST, BASE_64);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.PRECONDITION_FAILED));
+ }
+
+ @Test
+ public void testCrlPostEncodingDER() throws Exception {
+ getTestMethodName();
+ String thisUpdate = "20160831000000";
+ String nextUpdate = "20161123000000";
+ byte[] crl = CrlIssuer.CRL_ISSUER.generate(DATE_FORMAT.parse(thisUpdate),
+ DATE_FORMAT.parse(nextUpdate), Collections.emptyList());
+ IRequest request = crlRequest(RequestMethod.POST, thisUpdate, nextUpdate, crl, DER);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CHANGED));
+ request = crlRequest(RequestMethod.GET, CRL_URI, CRL_URI_QUERY);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(methodCheck(mResponse, ResponseStatus.CONTENT));
+ assertEquals(DER, crlMap.get(Constants.ENCODING));
+ assertTrue(Arrays.equals(crl, data));
+ assertTrue(Arrays.equals(crl, crlX509.getEncoded()));
+ }
@Test
public void testCrlBadRequest() throws Exception {
getTestMethodName();
IRequest request = crlRequest(RequestMethod.PUT, CRL_URI, null);
- certificateResource.onDefaultRequestReceived(mMockDevice, request);
+ crlResource.onDefaultRequestReceived(mMockDevice, request);
+ assertTrue(mResponse.getStatus().equals(ResponseStatus.BAD_REQUEST));
}
- private IRequest crlRequest(RequestMethod method, String uri, String query) {
+ public static IRequest crlRequest(RequestMethod method, String uri, String query) {
IRequest request = MessageBuilder.createRequest(method, uri, query);
return request;
}
- private IRequest crlRequest(RequestMethod method, String thisUpdate, String nextUpdate, String rcsn) {
+ private IRequest crlRequestSN(RequestMethod method, String[] keys, Object[] values) {
HashMap<String, Object> payloadData = new HashMap<>();
- payloadData.put(Constants.REQ_THIS_UPDATE, thisUpdate);
+ for (int i = 0; i < keys.length; i++) {
+ payloadData.put(keys[i], values[i]);
+ }
+ IRequest request = MessageBuilder.createRequest(method, CRL_URI,
+ null, ContentFormat.APPLICATION_CBOR,
+ mCbor.encodingPayloadToCbor(payloadData));
+ return request;
+ }
+
+ private IRequest crlRequestFull(RequestMethod method, String[] keys, Object[] values, String encoding) {
+ HashMap<String, Object> payloadData = new HashMap<>();
+ if (keys.length != 0 && values.length != 0) {
+ for (int i = 0; i < keys.length - 1; i++) {
+ payloadData.put(keys[i], values[i]);
+ }
+ Object value = values[values.length - 1];
+ if (value instanceof byte[]) {
+ payloadData.put(keys[keys.length - 1], new CRL(encoding, (byte[]) value));
+ } else {
+ payloadData.put(keys[keys.length - 1], value);
+ }
- payloadData.put(Constants.REQ_NEXT_UPDATE, nextUpdate);
- payloadData.put(Constants.REQ_SERIAL_NUMBER, rcsn);
+ }
IRequest request = MessageBuilder.createRequest(method, CRL_URI,
null, ContentFormat.APPLICATION_CBOR,
mCbor.encodingPayloadToCbor(payloadData));
}
+ private IRequest crlRequest(RequestMethod method, String thisUpdate, String nextUpdate, String[] rcsn) {
+ return crlRequestSN(method, FOR_SERIAL_NUMBER, new Object[]{thisUpdate, nextUpdate, rcsn});
+ }
+
+ private IRequest crlRequestFailedCRL(RequestMethod method, String thisUpdate, String nextUpdate, String[] rcsn) {
+ return crlRequestSN(method, FOR_SERIAL_NUMBER, new Object[]{thisUpdate, nextUpdate, rcsn.length});
+ }
+
+ private IRequest crlRequest(RequestMethod method, String thisUpdate, String nextUpdate, byte[] crl, String encoding) {
+ return crlRequestFull(method, FOR_FULL_CRL, new Object[]{thisUpdate, nextUpdate, crl}, encoding);
+ }
+
+ private IRequest crlRequestFailedCRL(RequestMethod method, String thisUpdate, String nextUpdate,
+ String encoding) {
+ return crlRequestFull(method, FOR_FULL_CRL, new Object[]{thisUpdate, nextUpdate, thisUpdate}, encoding);
+ }
+
+ private IRequest crlRequestFailedDate(RequestMethod method, String thisUpdate, String nextUpdate,
+ String encoding) {
+ return crlRequestFull(method, FOR_FULL_CRL, new Object[]{thisUpdate.getBytes(), nextUpdate, thisUpdate}, encoding);
+ }
+
+ private IRequest crlRequestFailedPayload(RequestMethod method, String encoding) {
+ return crlRequestFull(method, new String[]{}, new Object[]{}, encoding);
+ }
+
+ private static final class CRL {
+
+ private final String encoding;
+
+ private final byte[] data;
+
+ public CRL(String encoding, byte[] data) {
+ this.encoding = encoding;
+ this.data = data;
+ }
+
+ @Override
+ public String toString() {
+ return "CRL{" +
+ "encoding='" + encoding + '\'' +
+ ", data=" + Arrays.toString(data) +
+ '}';
+ }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+ }
+
+
private void getTestMethodName() {
StackTraceElement[] stacks = new Throwable().getStackTrace();
StackTraceElement currentStack = stacks[1];
return false;
}
-
private boolean hashmapCheck(IResponse response, String propertyName) {
- HashMap<String, Object> payloadData = mCbor
+ Map<String, Object> payloadData = mCbor
.parsePayloadFromCbor(response.getPayload(), HashMap.class);
if (payloadData.containsKey(propertyName))
return true;