--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#ifndef INCLUDE_ISSUER_ISSUER_H_
+#define INCLUDE_ISSUER_ISSUER_H_
+
+#include "Certificate.h" // Certificate ASN.1 type
+#include "pki.h"
+#include "pki_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define X509_V1 0
+#define X509_V2 1
+#define X509_V3 2
+
+/**
+ * Encodes X.509 certificate with specified parameters.
+ *
+ * @param[in] subjectName pointer to serial subject's common name
+ * @param[in] issuerName pointer to issuer's common name
+ * @param[in] notBefore pointer to certificate validity limit
+ * @param[in] notAfter pointer to certificate validity limit
+ * @param[in] subjectPublicKey pointer to subject's public key to be signed
+ * @param[in] issuerPrivateKey pointer to issuer's private key to sign certificate
+ * @param[out] encodedCertificate pointer to allocated memory for DER encoded certificate
+ * (ISSUER_MAX_CERT_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateCertificate (const UTF8String_t *subjectName, const UTF8String_t *issuerName,
+ const UTCTime_t *notBefore, const UTCTime_t *notAfter,
+ const BIT_STRING_t *subjectPublicKey, const BIT_STRING_t *issuerPrivateKey,
+ ByteArray *encodedCertificate);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDE_ISSUER_ISSUER_H_ */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+ ******************************************************************/
+
+#ifndef INCLUDE_MASTER_ISSUER_H_
+#define INCLUDE_MASTER_ISSUER_H_
+
+#include "byte_array.h"
+#include "cert_generator.h"
+#include "ckm_info.h"
+#include "csr_generator.h"
+#include "ecc.h"
+#include "crl_generator.h"
+#include "pki_errors.h"
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ISSUER_DEFAULT_CA_NAME "CA_name"
+#define ISSUER_DEFAULT_SUBJECT_NAME "Subj_name"
+#define ISSUER_DEFAULT_NOT_BEFORE "130101000000Z"
+#define ISSUER_DEFAULT_NOT_AFTER "490101000000Z"
+#define ISSUER_DEFAULT_THIS_UPDATE "150601000000Z"
+
+/**
+ * Set serial number for next certificate and save it in the CA storage.
+ *
+ * Used by CKMSetCAInfo()
+ *
+ * @param[in] serNum certificate serial number to be set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetSerialNumber (const long serNum);
+
+/**
+ * Set CA common name and save it in the CA storage.
+ *
+ * Used by CKMSetCAInfo()
+ *
+ * @param[in] rootName CA common name to be set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetRootName (const ByteArray rootName);
+
+/**
+ * Set CA info and save it in the CA storage.
+ *
+ * Should be called before certificate generation
+ *
+ * @param[in] serNum certificate serial number to be set
+ * @param[in] rootName CA common name to be set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CKMSetCAInfo (const long serNum, const ByteArray rootName);
+
+/**
+ * Generate key pair for CA.
+ *
+ * Should be called before certificate generation
+ *
+ * @param[out] caPrivateKey pointer to allocated ByteArray for CA private key
+ * @param[out] caPublicKey pointer to allocated ByteArray for CA public key
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateCAKeyPair (ByteArray *caPrivateKey, ByteArray *caPublicKey);
+
+/**
+ * Issues X.509 certificate with specified parameters.
+ *
+ * SetSerialNumber, SetRootName and GenerateCAKeyPair should be called before.
+ *
+ * @param[in] uint8NotBefore pointer to string with certificate validity limit
+ * or 0 to use default value
+ * @param[in] uint8NotAfter pointer to string with certificate validity limit
+ * or 0 to use default value
+ * @param[out] issuedCertificate pointer to allocated memory for DER encoded certificate
+ * (ISSUER_MAX_CERT_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CKMIssueRootCertificate (const uint8_t *uint8NotBefore, const uint8_t *uint8NotAfter,
+ ByteArray *issuedRootCertificate);
+
+/**
+ * Generate key pair for ordinary device.
+ *
+ * @param[out] privateKey pointer to allocated ByteArray for private key
+ * @param[out] publicKey pointer to allocated ByteArray for public key
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateKeyPair (ByteArray *privateKey, ByteArray *publicKey);
+
+/**
+ * Issues X.509 certificate with specified parameters.
+ *
+ * SetSerialNumber, SetRootName and GenerateCAKeyPair should be called before.
+ *
+ * @param[in] uint8SubjectName pointer to string with serial subject's common name
+ * or 0 to use default value
+ * @param[in] uint8NotBefore pointer to string with certificate validity limit
+ * or 0 to use default value
+ * @param[in] uint8NotAfter pointer to string with certificate validity limit
+ * or 0 to use default value
+ * @param[in] uint8SubjectPublicKey pointer to array with subject's public key to be signed
+ * @param[out] issuedCertificate pointer to allocated memory for DER encoded certificate
+ * (ISSUER_MAX_CERT_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CKMIssueDeviceCertificate (const uint8_t *uint8SubjectName,
+ const uint8_t *uint8NotBefore, const uint8_t *uint8NotAfter,
+ const uint8_t *uint8SubjectPublicKey,
+ ByteArray *issuedCertificate);
+
+/**
+ * Write certificate into specified file.
+ *
+ * @param[in] certificate pointer to DER-encoded certificate that should be written into the file
+ * @param[in] certFileName pointer to null-terminated string with file name
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char *certFileName);
+
+/**
+ * Issues certificate signing request with specified parameters.
+ *
+ * @param[in] uint8SubjectName pointer to string with serial subject's common name
+ * or 0 to use default value
+ * @param[in] uint8SubjectPublicKey pointer to array with subject's public key to be signed
+ * @param[in] uint8SubjectPrivateKey pointer to array with subject's private key to be signed
+ * @param[out] encodedCSR pointer to allocated memory for DER encoded certificate signing request
+ * (CSR_MAX_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateCSR (const uint8_t *uint8SubjectName,
+ const uint8_t *uint8SubjectPublicKey,
+ const uint8_t *uint8SubjectPrivateKey,
+ ByteArray *encodedCSR);
+
+/**
+ * Issues X.509 certificate based on certificate signing request.
+ *
+ * @param[in] encodedCSR pointer to array with DER encoded certificate signing request
+ * @param[out] issuedCertificate pointer to allocated memory for DER encoded certificate
+ * (MAX_CERT_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateCertificateByCSR (const ByteArray *encodedCSR, ByteArray *issuedCertificate);
+
+/**
+ * Generate certificate revocation list with specified parameters.
+ *
+ * @param[in] thisUpdateTime pointer to time of issuing CRL or 0 to use default
+ * @param[in] nuberOfRevoked number of revoked certificates
+ * @param[in] revokedNumbers array with numbers of revoked certificates
+ * @param[in] revocationDates
+ * @param[out] encodedCRL pointer to allocated memory for DER encoded certificate revocation list
+ * ( (CRL_MIN_SIZE + nuberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4)) bytes
+ * should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CKMIssueCRL (const uint8_t *uint8ThisUpdateTime, const uint32_t nuberOfRevoked,
+ const uint32_t *revokedNumbers, const uint8_t **revocationDates,
+ ByteArray *encodedCRL);
+
+/**
+ * Gets current certificate revocation list.
+ *
+ * @param[out] certificateRevocationList pointer to the certificate revocation list to get
+ * (Memory should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CKMGetCRL (ByteArray *certificateRevocationList);
+
+/**
+ * Add specified certificate into certificate revocation list.
+ *
+ * @param[in] thisUpdateTime pointer to time of issuing CRL or 0 to use default
+ * @param[in] revokedNumber number of certificate to revoke
+ * @param[out] encodedCRL pointer to allocated memory for DER encoded certificate revocation list
+ * ( (CRL_MIN_SIZE + number of ALL revoked certificates *
+ * (sizeof(CertificateRevocationInfo_t) + 4)) bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CKMRevocateCertificate (const uint8_t *uint8ThisUpdateTime, const long revokedNumber,
+ ByteArray *encodedCRL);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDE_MASTER_ISSUER_H_ */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#ifndef INCLUDE_CA_STORAGE_H_
+#define INCLUDE_CA_STORAGE_H_
+
+#include "byte_array.h"
+#include <stdio.h>
+#include "pki_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CA_STORAGE_FILE "ckminfo.dat"
+#define CA_STORAGE_CRT_FILE "crt.der"
+#define ISSUER_MAX_NAME_SIZE (100)
+#define PRIVATE_KEY_SIZE (32)
+#define PUBLIC_KEY_SIZE (64)
+#define ISSUER_MAX_CERT_SIZE (1000)
+/**
+ * Certificate Authority storage
+ */
+typedef struct /*CA private key, CA certificate, other CA-related info*/
+{
+ uint8_t CKMInfoIsLoaded;
+
+ uint8_t CAPrivateKeyIsSet;
+ uint8_t CAPrivateKey[PRIVATE_KEY_SIZE];
+
+ uint8_t CAPublicKeyIsSet;
+ uint8_t CAPublicKey[PUBLIC_KEY_SIZE];
+
+ uint8_t CAChainLength;
+
+ ByteArray *CACertificateChain;
+
+ uint32_t CANameSize;
+ uint8_t CAName[ISSUER_MAX_NAME_SIZE];
+
+ long nextSerialNumber;
+
+ long CRLSerialNumber;
+
+ long numberOfRevoked;
+} CKMInfo_t;
+
+typedef struct /*CA private key, CA certificate, certificate revocation/white list*/
+{
+ uint32_t CRLsize;
+ uint8_t *certificateRevocationList;//should be allocated dynamically
+} CRLInfo_t;
+
+//General functions
+
+/**
+ * Initializes CA storage from CA_STORAGE_FILE.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError InitCKMInfo(void);
+
+/**
+ * Saves CA storage into CA_STORAGE_FILE.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SaveCKMInfo(void);
+
+/**
+ * Frees CA storage memory.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError CloseCKMInfo(void);
+
+/**
+ * Sets CKM Info.
+ *
+ * @param[in] nextSN pointer to the next serial number to set
+ * or 0 to skip this parameter
+ * @param[in] CRLSerialNumber pointer to the next CRL serial number to set
+ * or 0 to skip this parameter
+ * @param[in] CAPrivateKey pointer to the CA's private key to set
+ * or 0 to skip this parameter
+ * @param[in] CAPublicKey pointer to the CA's public key to set
+ * or 0 to skip this parameter
+ * @param[in] CAName pointer to the CA's common name to set
+ * or 0 to skip this parameter
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCKMInfo (const long *nextSN, const long *CRLSerialNumber,
+ const ByteArray *CAPrivateKey, const ByteArray *CAPublicKey,
+ const ByteArray *CAName);
+
+/**
+ * Gets CKM Info.
+ *
+ * @param[out] nextSN pointer to the next serial number to get
+ * (Memory should be allocated before call)
+ * or 0 to skip this parameter
+ * @param[out] CRLSerialNumber pointer to the next CRL serial number to get
+ * (Memory should be allocated before call)
+ * or 0 to skip this parameter
+ * @param[out] CAPrivateKey pointer to the CA's private key to get
+ * (PRIVATE_KEY_SIZE bytes should be allocated before call)
+ * or 0 to skip this parameter
+ * @param[out] CAPublicKey pointer to the CA's public key to get
+ * (PUBLIC_KEY_SIZE bytes should be allocated before call)
+ * or 0 to skip this parameter
+ * @param[out] CAName pointer to the CA's common name to get
+ * (ISSUER_MAX_NAME_SIZE bytes should be allocated before call)
+ * or 0 to skip this parameter
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCKMInfo (long *nextSN, long *CRLSerialNumber,
+ ByteArray *CAPrivateKey, ByteArray *CAPublicKey,
+ ByteArray *CAName);
+
+/**
+ * Sets CA's private key.
+ *
+ * @param[in] CAPrivateKey pointer to the CA's private key to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCAPrivateKey (const ByteArray *CAPrivateKey);
+
+/**
+ * Gets CA's private key.
+ *
+ * @param[out] CAPrivateKey pointer to the CA's private key to get
+ * (PRIVATE_KEY_SIZE bytes should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCAPrivateKey (ByteArray *CAPrivateKey);
+
+/**
+ * Sets CA's public key.
+ *
+ * @param[in] CAPublicKey pointer to the CA's public key to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCAPublicKey (const ByteArray *CAPublicKey);
+
+/**
+ * Gets CA's public key.
+ *
+ * @param[out] CAPublicKey pointer to the CA's public key to get
+ * (PUBLIC_KEY_SIZE bytes should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCAPublicKey (ByteArray *CAPublicKey);
+
+/**
+ * Sets CA's common name.
+ *
+ * @param[in] CAName pointer to the CA's common name to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCAName (const ByteArray *CAName);
+
+/**
+ * Gets CA's common name.
+ *
+ * @param[out] CAName pointer to the CA's common name to get
+ * (ISSUER_MAX_NAME_SIZE bytes should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCAName (ByteArray *CAName);
+
+//Certificate-related functions
+
+/**
+ * Initializes CA Certificate from CA_STORAGE_CRT_FILE.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError InitCRT(void);
+
+/**
+ * Saves CA Certificate into CA_STORAGE_CRT_FILE.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SaveCRT(void);
+
+/**
+ * Sets next serial number for certificate issuer.
+ *
+ * @param[in] nextSN pointer to the next serial number to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetNextSerialNumber (const long *nextSN);
+
+/**
+ * Gets next serial number for certificate issuer.
+ *
+ * @param[out] nextSN pointer to the next serial number to get
+ * (Memory should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetNextSerialNumber (long *nextSN);
+
+/**
+ * Sets DER encoded CA's certificate chain.
+ *
+ * @param[in] CAChain pointer to the CA's certificate to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCAChain (const uint8_t CAChainLength, const ByteArray *CAChain);
+
+/**
+ * Gets DER encoded CA's certificate chain.
+ *
+ * @param[out] CAChain pointer to allocated memory to get the CA's certificate chain
+ * (ISSUER_MAX_CHAIN_SIZE bytes should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCAChain (uint8_t* CAChainLength, ByteArray *CAChain);
+
+/**
+ * Sets DER encoded CA's certificate.
+ *
+ * @param[in] CACertificate pointer to the CA's certificate to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCACertificate (const ByteArray *CACertificate);
+
+/**
+ * Gets DER encoded CA's certificate.
+ *
+ * @param[out] CACertificate pointer to the CA's certificate to get
+ * (ISSUER_MAX_CERT_SIZE bytes should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCACertificate (ByteArray *CACertificate);
+
+//CRL-related functions
+
+/**
+ * Initializes CRL from CA_STORAGE_CRL_FILE.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError InitCRL(void);
+
+/**
+ * Saves CRL into CA_STORAGE_CRL_FILE.
+ *
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SaveCRL(void);
+
+/**
+ * Sets next CRL serial number for certificate issuer.
+ *
+ * @param[in] CRLSerialNumber pointer to the next CRL serial number to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCRLSerialNumber (const long *CRLSerialNumber);
+
+/**
+ * Gets next CRL serial number for certificate issuer.
+ *
+ * @param[out] CRLSerialNumber pointer to the next CRL serial number to get
+ * (Memory should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCRLSerialNumber (long *CRLSerialNumber);
+
+/**
+ * Sets current certificate revocation list.
+ *
+ * @param[in] certificateRevocationList pointer to the certificate revocation list to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetCertificateRevocationList (const ByteArray *certificateRevocationList);
+
+/**
+ * Gets current certificate revocation list.
+ *
+ * @param[out] certificateRevocationList pointer to the certificate revocation list to get
+ * (Memory should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetCertificateRevocationList (ByteArray *certificateRevocationList);
+
+/**
+ * Sets number of revoked certificates.
+ *
+ * @param[in] numberOfRevoked pointer to number of revoked certificates to set
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SetNumberOfRevoked (const long *numberOfRevoked);
+
+/**
+ * Gets number of revoked certificates.
+ *
+ * @param[out] numberOfRevoked pointer to number of revoked certificates to get
+ * (Memory should be allocated before call)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GetNumberOfRevoked (long *numberOfRevoked);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDE_CA_STORAGE_H_ */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#ifndef INCLUDE_MASTER_CRL_ENCODER_H_
+#define INCLUDE_MASTER_CRL_ENCODER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "CertificateRevocationList.h" /* CertificateList ASN.1 type */
+#include "pki.h"
+#include "pki_errors.h"
+
+// Minimal memory allocated for DER encoded CRL
+#define CRL_MIN_SIZE 250 //minimal size of CRL (issuer info + signature)
+
+#define CRL_MAX_NAME_SIZE 100 //maximal length of CRL issuer field
+
+/**
+ * Encode certificate revocation list with specified parameters.
+ *
+ * @param[in] issuerName pointer to issuer's common name
+ * @param[in] thisUpdateTime pointer to time of issuing CRL
+ * @param[in] nuberOfRevoked number of revoked certificates
+ * @param[in] certificateRevocationInfo array with certificate revocation info
+ * @param[in] issuerPrivateKey pointer to issuer's private key to sign CRL
+ * @param[out] encodedCRL pointer to allocated memory for DER encoded certificate revocation list
+ * ( (CRL_MIN_SIZE + nuberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4)) bytes
+ * should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError GenerateCRL (const UTF8String_t *issuerName,
+ const UTCTime_t *thisUpdateTime, const uint32_t nuberOfRevoked,
+ const CertificateRevocationInfo_t *certificateRevocationInfo,
+ const BIT_STRING_t *issuerPrivateKey, ByteArray *encodedCRL);
+
+/**
+ * Sign certificate revocation list.
+ *
+ * @param[in] certificateRevocationList pointer to CRL for signing
+ * @param[in] crlMaxSize max size of DER encoded CRL
+ * @param[in] issuerPrivateKey pointer to issuer private key
+ * @param[out] encodedCRL pointer to allocated memory for DER encoded certificate revocation list
+ * crlMaxSize bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError SignCRL(CertificateRevocationList_t *certificateRevocationList,
+ const uint32_t crlMaxSize, const BIT_STRING_t *issuerPrivateKey,
+ ByteArray *encodedCRL);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDE_MASTER_CRL_ENCODER_H_ */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#ifndef INCLUDE_MASTER_CSR_H_
+#define INCLUDE_MASTER_CSR_H_
+
+#include "CertificationRequest.h" /* CertificationRequest ASN.1 type */
+#include "pki.h"
+#include "pki_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Memory allocated for DER encoded CSR
+#define CSR_MAX_SIZE 1000
+
+#define CSR_DEFAULT_VERSION 0
+#define CSR_MAX_NAME_SIZE 100
+
+/**
+ * Encode certificate signing request with specified parameters.
+ *
+ * @param[in] subjectName pointer to subject's common name
+ * @param[in] subjectPublicKey pointer to subject's public key to be signed
+ * @param[in] subjectPrivateKey pointer to subject's private key to be signed
+ * @param[out] encodedCSR pointer to allocated memory for DER encoded certificate signing request
+ * (CSR_MAX_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError EncodeCSR (const UTF8String_t *subjectName,
+ const BIT_STRING_t *subjectPublicKey,
+ const BIT_STRING_t *subjectPrivateKey,
+ ByteArray *encodedCSR);
+
+/**
+ * Decode certificate signing request, extracts its common name and public key.
+ *
+ * Return error if signature is not valid.
+ *
+ * @param[in] encodedCSR pointer to array with DER encoded certificate signing request
+ * @param[out] subjectName pointer to allocated memory for subject's common name extraction
+ * (CSR_MAX_NAME_SIZE bytes should be allocated)
+ * @param[out] subjectPublicKey pointer to allocated memory for subject's public key extraction
+ * (PUBLIC_KEY_SIZE bytes should be allocated)
+ * @return PKI_SUCCESS if success, error code otherwise
+ */
+PKIError DecodeCSR (const ByteArray *encodedCSR,
+ UTF8String_t *subjectName, BIT_STRING_t *subjectPublicKey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDE_MASTER_CSR_H_ */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#include "cert_generator.h"
+#include "ckm_info.h"
+#include "pki.h"
+#include "oic_malloc.h"
+
+//ecdsa-with-SHA256 1.2.840.10045.4.3.2 [RFC5759]
+static const uint8_t g_ECDSA_WITH_SHA256_OID[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
+
+//Elliptic Curve Digital Signature Algorithm (ECDSA) 1.2.840.10045.2.1 [RFC7250]
+static const uint8_t g_EC_PUBLIC_KEY_OID[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01};
+
+//secp256r1 1.2.840.10045.3.1.7 [RFC5656]
+static const uint8_t g_PRIME_256_V1_OID[] = {0x2A, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
+
+//commonName 2.5.4.3 [RFC2256]
+static const uint8_t g_COMMON_NAME_OID[] = {0x55, 0x04, 0x03};
+
+
+PKIError GenerateCertificate (const UTF8String_t *subjectName, const UTF8String_t *issuerName,
+ const UTCTime_t *notBefore, const UTCTime_t *notAfter,
+ const BIT_STRING_t *subjectPublicKey, const BIT_STRING_t *issuerPrivateKey,
+ ByteArray *encodedCertificate)
+{
+ FUNCTION_INIT();
+ asn_enc_rval_t ec; /* Encoder return value */
+ Certificate_t *certificate = NULL; /* Type to encode */
+ AttributeTypeAndValue_t *issuerTypeAndValue = NULL;
+ AttributeTypeAndValue_t *subjectTypeAndValue = NULL;
+ RelativeDistinguishedName_t *issuerRDN = NULL;
+ RelativeDistinguishedName_t *subjectRDN = NULL;
+ uint8_t *uint8Pointer = NULL;
+ ByteArray tbs = BYTE_ARRAY_INITIALIZER;
+ uint8_t signature[SIGN_FULL_SIZE];
+ uint8_t sha256[SHA_256_HASH_LEN];
+ uint8_t tbsDer[ISSUER_MAX_CERT_SIZE];
+ long serialNumber = 0;
+
+ CHECK_NULL(subjectName, ISSUER_X509_NULL_PASSED);
+ CHECK_NULL(issuerName, ISSUER_X509_NULL_PASSED);
+ CHECK_NULL(notBefore, ISSUER_X509_NULL_PASSED);
+ CHECK_NULL(notAfter, ISSUER_X509_NULL_PASSED);
+ CHECK_NULL(subjectPublicKey, ISSUER_X509_NULL_PASSED);
+ CHECK_NULL(issuerPrivateKey, ISSUER_X509_NULL_PASSED);
+ CHECK_NULL_BYTE_ARRAY_PTR(encodedCertificate, ISSUER_X509_NULL_PASSED);
+ CHECK_LESS_EQUAL(ISSUER_MAX_CERT_SIZE, encodedCertificate->len,
+ ISSUER_X509_WRONG_BYTE_ARRAY_LEN);
+
+ /* Allocate the memory */
+ certificate = OICCalloc(1, sizeof(Certificate_t)); // not malloc!
+ CHECK_NULL(certificate, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ issuerTypeAndValue = OICCalloc(1, sizeof(AttributeTypeAndValue_t));
+ CHECK_NULL(issuerTypeAndValue, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ issuerRDN = OICCalloc(1, sizeof(RelativeDistinguishedName_t));
+ CHECK_NULL(issuerRDN, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ subjectTypeAndValue = OICCalloc(1, sizeof(AttributeTypeAndValue_t));
+ CHECK_NULL(subjectTypeAndValue, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ subjectRDN = OICCalloc(1, sizeof(RelativeDistinguishedName_t));
+ CHECK_NULL(subjectRDN, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ //set issuer name
+ issuerTypeAndValue->value = *issuerName;
+ issuerTypeAndValue->type.buf = (uint8_t *)g_COMMON_NAME_OID; //2.5.4.3
+ issuerTypeAndValue->type.size = sizeof(g_COMMON_NAME_OID) / sizeof(g_COMMON_NAME_OID[0]);
+ ASN_SET_ADD(issuerRDN, issuerTypeAndValue);
+ ASN_SEQUENCE_ADD(&(certificate->tbsCertificate.issuer), issuerRDN);
+
+ //set subject name
+ subjectTypeAndValue->value = *subjectName;
+ subjectTypeAndValue->type.buf = (uint8_t *)g_COMMON_NAME_OID; //2.5.4.3
+ subjectTypeAndValue->type.size = sizeof(g_COMMON_NAME_OID) / sizeof(g_COMMON_NAME_OID[0]);
+ ASN_SET_ADD(subjectRDN, subjectTypeAndValue);
+ ASN_SEQUENCE_ADD(&(certificate->tbsCertificate.subject), subjectRDN);
+
+ //set validity
+ certificate->tbsCertificate.validity.notBefore = *notBefore;
+ certificate->tbsCertificate.validity.notAfter = *notAfter;
+
+ //set X.509 certificate version
+ certificate->tbsCertificate.version = X509_V2;
+
+ //set serial number
+ certificate->tbsCertificate.serialNumber = 0;
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetNextSerialNumber, &serialNumber);
+ certificate->tbsCertificate.serialNumber = serialNumber;
+ serialNumber++;
+ CHECK_CALL(SetNextSerialNumber, &serialNumber);
+ CHECK_CALL(SaveCKMInfo);
+
+ //set signature algorithm in TBS
+ certificate->tbsCertificate.signature.algorithm.buf =
+ (uint8_t *)g_ECDSA_WITH_SHA256_OID; //1.2.840.10045.4.3.2
+ certificate->tbsCertificate.signature.algorithm.size =
+ sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
+ certificate->tbsCertificate.signature.nul = OICCalloc(1, sizeof(NULL_t));
+ CHECK_NULL(certificate->tbsCertificate.signature.nul, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ //set subject Public Key algorithm
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm.buf =
+ (uint8_t *)g_EC_PUBLIC_KEY_OID; //1.2.840.10045.2.1
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm.size =
+ sizeof(g_EC_PUBLIC_KEY_OID) / sizeof(g_EC_PUBLIC_KEY_OID[0]);
+
+ //set subject Public Key curve
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.id_ecPublicKey =
+ OICCalloc(1, sizeof(OBJECT_IDENTIFIER_t));
+ CHECK_NULL(certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.id_ecPublicKey,
+ ISSUER_X509_MEMORY_ALLOC_FAILED);
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.id_ecPublicKey->buf =
+ (uint8_t *)g_PRIME_256_V1_OID; //1.2.840.10045.3.1.7
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.id_ecPublicKey->size =
+ sizeof(g_PRIME_256_V1_OID) / sizeof(g_PRIME_256_V1_OID[0]);
+
+ //set subject Public Key
+ certificate->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = *subjectPublicKey;
+
+ //set signature algorithm
+ certificate->signatureAlgorithm.algorithm.buf = (uint8_t *)g_ECDSA_WITH_SHA256_OID;
+ certificate->signatureAlgorithm.algorithm.size =
+ sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
+ certificate->signatureAlgorithm.nul = OICCalloc(1, sizeof(NULL_t));
+ CHECK_NULL(certificate->signatureAlgorithm.nul, ISSUER_X509_MEMORY_ALLOC_FAILED);
+
+ //encode TBS to DER
+ ec = der_encode_to_buffer(&asn_DEF_TBSCertificate, &(certificate->tbsCertificate),
+ tbsDer, ISSUER_MAX_CERT_SIZE);
+ CHECK_COND(ec.encoded > 0, ISSUER_X509_DER_ENCODE_FAIL);
+ tbs.len = ec.encoded;
+ tbs.data = tbsDer;
+ GET_SHA_256(tbs, sha256);
+ CHECK_COND(uECC_sign((issuerPrivateKey->buf) + 1, sha256, signature),
+ ISSUER_X509_SIGNATURE_FAIL);
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+
+ // ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } (RFC 5480)
+ certificate->signatureValue.size = SIGN_FULL_SIZE + 6;// size for SEQUENCE ID + 2 * INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[0] > 127)
+ {
+ certificate->signatureValue.size ++;
+ }
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[SIGN_R_LEN] > 127)
+ {
+ certificate->signatureValue.size ++;
+ }
+ certificate->signatureValue.buf = OICCalloc(certificate->signatureValue.size, sizeof(uint8_t));
+ CHECK_NULL(certificate->signatureValue.buf, ISSUER_X509_MEMORY_ALLOC_FAILED);
+ *(certificate->signatureValue.buf) = (12 << 2); //ASN.1 SEQUENCE ID
+ *(certificate->signatureValue.buf + 1) = certificate->signatureValue.size - 2;
+ //ASN.1 SEQUENCE size
+
+ uint8Pointer = certificate->signatureValue.buf + 2; //skip SEQUENCE ID and size
+ *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[0] > 127)
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN + 1; //ASN.1 INTEGER size
+ uint8Pointer += 3; //skip INTEGER ID and size
+ }
+ else
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN; //ASN.1 INTEGER SIZE
+ uint8Pointer += 2; //skip INTEGER ID and size
+ }
+ memcpy(uint8Pointer, signature, SIGN_R_LEN);
+
+ uint8Pointer += SIGN_R_LEN; //skip first part of signature
+ *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature [SIGN_R_LEN] > 127)
+ {
+ *(uint8Pointer + 1) = SIGN_S_LEN + 1; //ASN.1 INTEGER size
+ uint8Pointer += 3; //skip INTEGER ID and size
+ }
+ else
+ {
+ *(uint8Pointer + 1) = SIGN_S_LEN; //ASN.1 INTEGER size
+ uint8Pointer += 2; //skip INTEGER ID and size
+ }
+ memcpy(uint8Pointer, signature + SIGN_R_LEN, SIGN_S_LEN);
+
+ ec = der_encode_to_buffer(&asn_DEF_Certificate, certificate,
+ encodedCertificate->data, ISSUER_MAX_CERT_SIZE);
+ CHECK_COND(ec.encoded > 0, ISSUER_X509_DER_ENCODE_FAIL);
+ encodedCertificate->len = ec.encoded;
+
+ FUNCTION_CLEAR(
+ if (issuerTypeAndValue)
+ {
+ issuerTypeAndValue->value.buf = NULL;
+ issuerTypeAndValue->type.buf = NULL;
+ }
+ if (subjectTypeAndValue)
+ {
+ subjectTypeAndValue->value.buf = NULL;
+ subjectTypeAndValue->type.buf = NULL;
+ }
+ if (certificate)
+ {
+ certificate->tbsCertificate.validity.notBefore.buf = NULL;
+ certificate->tbsCertificate.validity.notAfter.buf = NULL;
+ certificate->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.buf = NULL;
+ certificate->tbsCertificate.signature.algorithm.buf = NULL;
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm.buf = NULL;
+ certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.id_ecPublicKey->buf = NULL;
+ certificate->signatureAlgorithm.algorithm.buf = NULL;
+ }
+ ASN_STRUCT_FREE(asn_DEF_Certificate, certificate);
+ certificate = NULL;
+ );
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+#include "ck_manager.h"
+#include "crlresource.h"
+#include "oic_malloc.h"
+
+/* The first octet of the OCTET STRING indicates whether the key is
+compressed or uncompressed. The uncompressed form is indicated by 0x04
+and the compressed form is indicated by either 0x02 or 0x03 (RFC 5480)*/
+#define ASN1_UNCOMPRESSED_KEY_ID (0x04)
+
+PKIError GenerateCAKeyPair (ByteArray *caPrivateKey, ByteArray *caPublicKey)
+{
+ FUNCTION_INIT();
+
+ CHECK_NULL(caPrivateKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(caPrivateKey->data, ISSUER_NULL_PASSED);
+ CHECK_NULL(caPublicKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(caPublicKey->data, ISSUER_NULL_PASSED);
+
+ CHECK_COND(uECC_make_key(caPublicKey->data, caPrivateKey->data), ISSUER_MAKE_KEY_ERROR);
+ caPublicKey->len = PUBLIC_KEY_SIZE;
+ caPrivateKey->len = PRIVATE_KEY_SIZE;
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(SetCAPrivateKey, caPrivateKey);
+ CHECK_CALL(SetCAPublicKey, caPublicKey);
+ CHECK_CALL(SaveCKMInfo);
+ FUNCTION_CLEAR();
+}
+
+PKIError CKMIssueRootCertificate (const uint8_t *uint8NotBefore, const uint8_t *uint8NotAfter,
+ ByteArray *issuedRootCertificate)
+{
+ FUNCTION_INIT();
+
+ UTF8String_t *rootName = NULL;
+ UTCTime_t *notBefore = NULL;
+ UTCTime_t *notAfter = NULL;
+ BIT_STRING_t *subjectPublicKey = NULL;
+ BIT_STRING_t *issuerPrivateKey = NULL;
+
+ ByteArray pubKeyIss = BYTE_ARRAY_INITIALIZER;
+ ByteArray privKeyIss = BYTE_ARRAY_INITIALIZER;
+ ByteArray caName = BYTE_ARRAY_INITIALIZER;
+
+ uint8_t caPublicKey[PUBLIC_KEY_SIZE];
+ uint8_t caPrivateKey[PRIVATE_KEY_SIZE];
+ uint8_t uint8caName[ISSUER_MAX_NAME_SIZE];
+
+ CHECK_NULL(issuedRootCertificate, ISSUER_NULL_PASSED);
+ CHECK_NULL(issuedRootCertificate->data, ISSUER_NULL_PASSED);
+ CHECK_LESS_EQUAL(ISSUER_MAX_CERT_SIZE, issuedRootCertificate->len, ISSUER_WRONG_BYTE_ARRAY_LEN);
+
+ pubKeyIss.data = caPublicKey;
+ pubKeyIss.len = PUBLIC_KEY_SIZE;
+ privKeyIss.data = caPrivateKey;
+ privKeyIss.len = PRIVATE_KEY_SIZE;
+ caName.data = uint8caName;
+ caName.len = ISSUER_MAX_NAME_SIZE;
+
+ rootName = (UTF8String_t *)OICCalloc(1, sizeof(UTF8String_t));
+ CHECK_NULL(rootName, ISSUER_MEMORY_ALLOC_FAILED);
+
+ notBefore = (UTCTime_t *)OICCalloc(1, sizeof(UTCTime_t));
+ CHECK_NULL(notBefore, ISSUER_MEMORY_ALLOC_FAILED);
+
+ notAfter = (UTCTime_t *)OICCalloc(1, sizeof(UTCTime_t));
+ CHECK_NULL(notAfter, ISSUER_MEMORY_ALLOC_FAILED);
+
+ subjectPublicKey = (BIT_STRING_t *)OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(subjectPublicKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ issuerPrivateKey = (BIT_STRING_t *)OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(issuerPrivateKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ //RootName
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAName, &caName);
+ rootName->buf = caName.data;
+ rootName->size = caName.len;
+
+ //notBefore
+ if (uint8NotBefore)
+ {
+ notBefore->buf = (uint8_t *)uint8NotBefore;
+ }
+ else
+ {
+ notBefore->buf = (uint8_t *)ISSUER_DEFAULT_NOT_BEFORE;
+ }
+ notBefore->size = strlen((const char *)notBefore->buf);
+
+ //notAfter
+ if (uint8NotAfter)
+ {
+ notAfter->buf = (uint8_t *)uint8NotAfter;
+ }
+ else
+ {
+ notAfter->buf = (uint8_t *)ISSUER_DEFAULT_NOT_AFTER;
+ }
+ notAfter->size = strlen((const char *)notAfter->buf);
+
+ //common keys
+ issuerPrivateKey->size = PRIVATE_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ issuerPrivateKey->buf = (uint8_t *)OICCalloc((issuerPrivateKey->size), sizeof(uint8_t));
+ CHECK_NULL(issuerPrivateKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(issuerPrivateKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+
+ subjectPublicKey->size = PUBLIC_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ subjectPublicKey->buf = (uint8_t *)OICCalloc(subjectPublicKey->size, sizeof(uint8_t));
+ CHECK_NULL(subjectPublicKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(subjectPublicKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+ //common keys
+
+ //read CA key pair from the CA storage
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAPrivateKey, &privKeyIss);
+
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((issuerPrivateKey->buf) + 1, privKeyIss.data, PRIVATE_KEY_SIZE);
+ CHECK_CALL(GetCAPublicKey, &pubKeyIss);
+
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((subjectPublicKey->buf) + 1, pubKeyIss.data, PUBLIC_KEY_SIZE);
+
+ CHECK_CALL(GenerateCertificate, rootName, rootName, notBefore, notAfter,
+ subjectPublicKey, issuerPrivateKey, issuedRootCertificate);
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(SetCACertificate, issuedRootCertificate);
+ CHECK_CALL(SaveCKMInfo);
+
+ FUNCTION_CLEAR(
+ OICFree(rootName);
+ OICFree(notBefore);
+ OICFree(notAfter);
+ ASN_STRUCT_FREE(asn_DEF_BIT_STRING, subjectPublicKey);
+ ASN_STRUCT_FREE(asn_DEF_BIT_STRING, issuerPrivateKey);
+ );
+}
+
+PKIError GenerateKeyPair (ByteArray *privateKey, ByteArray *publicKey)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(privateKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(privateKey->data, ISSUER_NULL_PASSED);
+ CHECK_NULL(publicKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(publicKey->data, ISSUER_NULL_PASSED);
+ CHECK_COND(uECC_make_key(publicKey->data, privateKey->data), ISSUER_MAKE_KEY_ERROR);
+ publicKey->len = PUBLIC_KEY_SIZE;
+ privateKey->len = PRIVATE_KEY_SIZE;
+ FUNCTION_CLEAR();
+}
+
+PKIError CKMIssueDeviceCertificate (const uint8_t *uint8SubjectName,
+ const uint8_t *uint8NotBefore, const uint8_t *uint8NotAfter,
+ const uint8_t *uint8SubjectPublicKey,
+ ByteArray *issuedCertificate)
+{
+ FUNCTION_INIT();
+
+ UTF8String_t *subjectName = NULL;
+ UTF8String_t *issuerName = NULL;
+ UTCTime_t *notBefore = NULL;
+ UTCTime_t *notAfter = NULL;
+ BIT_STRING_t *subjectPublicKey = NULL;
+ BIT_STRING_t *issuerPrivateKey = NULL;
+
+ ByteArray privKeyIss = BYTE_ARRAY_INITIALIZER;
+ ByteArray pubKeySubj = BYTE_ARRAY_INITIALIZER;
+ ByteArray privKeySubj = BYTE_ARRAY_INITIALIZER;
+ ByteArray caName = BYTE_ARRAY_INITIALIZER;
+
+ uint8_t subjPubKey[PUBLIC_KEY_SIZE];
+ uint8_t subjPrivKey[PRIVATE_KEY_SIZE];
+ uint8_t caPrivateKey[PRIVATE_KEY_SIZE];
+ uint8_t uint8caName[ISSUER_MAX_NAME_SIZE];
+
+ CHECK_NULL(uint8SubjectPublicKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(issuedCertificate, ISSUER_NULL_PASSED);
+ CHECK_NULL(issuedCertificate->data, ISSUER_NULL_PASSED);
+ CHECK_LESS_EQUAL(ISSUER_MAX_CERT_SIZE, issuedCertificate->len, ISSUER_WRONG_BYTE_ARRAY_LEN);
+
+ privKeyIss.data = caPrivateKey;
+ privKeyIss.len = PRIVATE_KEY_SIZE;
+ pubKeySubj.data = subjPubKey;
+ pubKeySubj.len = PUBLIC_KEY_SIZE;
+ privKeySubj.data = subjPrivKey;
+ privKeySubj.len = PRIVATE_KEY_SIZE;
+ caName.data = uint8caName;
+ caName.len = ISSUER_MAX_NAME_SIZE;
+
+ subjectName = (UTF8String_t *)OICCalloc(1, sizeof(UTF8String_t));
+ CHECK_NULL(subjectName, ISSUER_MEMORY_ALLOC_FAILED);
+
+ issuerName = (UTF8String_t *)OICCalloc(1, sizeof(UTF8String_t));
+ CHECK_NULL(issuerName, ISSUER_MEMORY_ALLOC_FAILED);
+
+ notBefore = (UTCTime_t *)OICCalloc(1, sizeof(UTCTime_t));
+ CHECK_NULL(notBefore, ISSUER_MEMORY_ALLOC_FAILED);
+
+ notAfter = (UTCTime_t *)OICCalloc(1, sizeof(UTCTime_t));
+ CHECK_NULL(notAfter, ISSUER_MEMORY_ALLOC_FAILED);
+
+ subjectPublicKey = (BIT_STRING_t *)OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(subjectPublicKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ issuerPrivateKey = (BIT_STRING_t *)OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(issuerPrivateKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ //SubjectName
+ if (uint8SubjectName)
+ {
+ subjectName->buf = (uint8_t *)uint8SubjectName;
+ }
+ else
+ {
+ subjectName->buf = (uint8_t *)ISSUER_DEFAULT_SUBJECT_NAME;
+ }
+ subjectName->size = strlen((const char *)subjectName->buf);
+
+ //IssuerName
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAName, &caName);
+ issuerName->buf = caName.data;
+ issuerName->size = caName.len;
+
+ //notBefore
+ if (uint8NotBefore)
+ {
+ notBefore->buf = (uint8_t *)uint8NotBefore;
+ }
+ else
+ {
+ notBefore->buf = (uint8_t *)ISSUER_DEFAULT_NOT_BEFORE;
+ }
+ notBefore->size = strlen((const char *)notBefore->buf);
+
+ //notAfter
+ if (uint8NotAfter)
+ {
+ notAfter->buf = (uint8_t *)uint8NotAfter;
+ }
+ else
+ {
+ notAfter->buf = (uint8_t *)ISSUER_DEFAULT_NOT_AFTER;
+ }
+ notAfter->size = strlen((const char *)notAfter->buf);
+
+ //common keys
+ issuerPrivateKey->size = PRIVATE_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ issuerPrivateKey->buf = (uint8_t *)OICCalloc((issuerPrivateKey->size), sizeof(uint8_t));
+ CHECK_NULL(issuerPrivateKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(issuerPrivateKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+
+ subjectPublicKey->size = PUBLIC_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ subjectPublicKey->buf = (uint8_t *)OICCalloc(subjectPublicKey->size, sizeof(uint8_t));
+ CHECK_NULL(subjectPublicKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(subjectPublicKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+ //common keys
+
+ //read CA private key from the CA storage
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAPrivateKey, &privKeyIss);
+
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((issuerPrivateKey->buf) + 1, privKeyIss.data, PRIVATE_KEY_SIZE);
+
+ if (!uint8SubjectPublicKey)
+ {
+ //GenerateKeyPair
+ GenerateKeyPair(&privKeySubj, &pubKeySubj);
+ }
+ else
+ {
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((subjectPublicKey->buf) + 1, uint8SubjectPublicKey, PUBLIC_KEY_SIZE);
+ }
+
+ CHECK_CALL(GenerateCertificate, subjectName, issuerName, notBefore, notAfter,
+ subjectPublicKey, issuerPrivateKey, issuedCertificate);
+
+ FUNCTION_CLEAR(
+ OICFree(subjectName);
+ OICFree(issuerName);
+ OICFree(notBefore);
+ OICFree(notAfter);
+ ASN_STRUCT_FREE(asn_DEF_BIT_STRING, subjectPublicKey);
+ ASN_STRUCT_FREE(asn_DEF_BIT_STRING, issuerPrivateKey);
+ );
+}
+
+PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char *certFileName)
+{
+ FUNCTION_INIT();
+ FILE *filePointer = NULL;
+
+ CHECK_NULL(certFileName, ISSUER_NULL_PASSED);
+ CHECK_NULL(certificate, ISSUER_NULL_PASSED);
+ CHECK_NULL(certificate->data, ISSUER_NULL_PASSED);
+ filePointer = fopen(certFileName, "wb");
+ CHECK_NULL(filePointer, ISSUER_FILE_WRITE_ERROR);
+ CHECK_EQUAL(fwrite(certificate->data, 1, certificate->len, filePointer), certificate->len,
+ ISSUER_FILE_WRITE_ERROR);
+
+ FUNCTION_CLEAR(
+ if(filePointer)
+ {
+ fclose(filePointer);
+ }
+ filePointer = NULL;
+ );
+}
+
+PKIError SetSerialNumber (const long serNum)
+{
+ FUNCTION_INIT();
+
+ CHECK_LESS_EQUAL(0, serNum, ISSUER_WRONG_SERIAL_NUMBER);
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(SetNextSerialNumber, &serNum);
+ CHECK_CALL(SaveCKMInfo);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError SetRootName (const ByteArray rootName)
+{
+ FUNCTION_INIT();
+
+ CHECK_NULL(rootName.data, ISSUER_NULL_PASSED);
+ CHECK_LESS(0, rootName.len, ISSUER_WRONG_ROOT_NAME_LEN);
+ CHECK_LESS(rootName.len, ISSUER_MAX_NAME_SIZE, ISSUER_WRONG_ROOT_NAME_LEN);
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(SetCAName, &rootName);
+ CHECK_CALL(SaveCKMInfo);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError CKMSetCAInfo (const long serNum, const ByteArray rootName)
+{
+ FUNCTION_INIT();
+ CHECK_CALL(SetSerialNumber, serNum);
+ CHECK_CALL(SetRootName, rootName);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GenerateCSR (const uint8_t *uint8SubjectName,
+ const uint8_t *uint8SubjectPublicKey,
+ const uint8_t *uint8SubjectPrivateKey,
+ ByteArray *encodedCSR)
+{
+ FUNCTION_INIT();
+ UTF8String_t *subjectName = NULL;
+ BIT_STRING_t *subjectPublicKey = NULL;
+ BIT_STRING_t *subjectPrivateKey = NULL;
+
+ CHECK_NULL(uint8SubjectPublicKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(uint8SubjectPrivateKey, ISSUER_NULL_PASSED);
+ CHECK_NULL(encodedCSR, ISSUER_NULL_PASSED);
+ CHECK_NULL(encodedCSR->data, ISSUER_NULL_PASSED);
+ CHECK_LESS_EQUAL(CSR_MAX_SIZE, encodedCSR->len, ISSUER_WRONG_BYTE_ARRAY_LEN);
+
+ subjectName = OICCalloc(1, sizeof(UTF8String_t));
+ CHECK_NULL(subjectName, ISSUER_MEMORY_ALLOC_FAILED);
+
+ subjectPublicKey = OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(subjectPublicKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ subjectPrivateKey = OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(subjectPrivateKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ //SubjectName
+ if (uint8SubjectName)
+ {
+ subjectName->buf = (uint8_t *)uint8SubjectName;
+ }
+ else
+ {
+ subjectName->buf = (uint8_t *)ISSUER_DEFAULT_SUBJECT_NAME;
+ }
+ subjectName->size = strlen((const char *)subjectName->buf);
+
+ //common keys
+ subjectPrivateKey->size = PRIVATE_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ subjectPrivateKey->buf = (uint8_t *)OICCalloc((subjectPrivateKey->size), sizeof(uint8_t));
+ CHECK_NULL(subjectPrivateKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(subjectPrivateKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+
+ subjectPublicKey->size = PUBLIC_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ subjectPublicKey->buf = (uint8_t *)OICCalloc(subjectPublicKey->size, sizeof(uint8_t));
+ CHECK_NULL(subjectPublicKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(subjectPublicKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+ //common keys
+
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((subjectPrivateKey->buf) + 1, uint8SubjectPrivateKey, PRIVATE_KEY_SIZE);
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((subjectPublicKey->buf) + 1, uint8SubjectPublicKey, PUBLIC_KEY_SIZE);
+
+ CHECK_CALL(EncodeCSR, subjectName, subjectPublicKey, subjectPrivateKey, encodedCSR);
+
+ FUNCTION_CLEAR(
+ OICFree(subjectName);
+ OICFree(subjectPublicKey);
+ OICFree(subjectPrivateKey->buf);
+ OICFree(subjectPrivateKey);
+ );
+}
+
+PKIError GenerateCertificateByCSR (const ByteArray *encodedCSR, ByteArray *issuedCertificate)
+{
+ FUNCTION_INIT();
+ UTF8String_t *subjectName = NULL;
+ BIT_STRING_t *subjectPublicKey = NULL;
+ uint8_t uint8SubjectName[ISSUER_MAX_NAME_SIZE];
+ uint8_t uint8SubjectPublicKey[PUBLIC_KEY_SIZE + 1];
+
+ CHECK_NULL(encodedCSR, ISSUER_NULL_PASSED);
+ CHECK_NULL(encodedCSR->data, ISSUER_NULL_PASSED);
+ CHECK_NULL(issuedCertificate, ISSUER_NULL_PASSED);
+ CHECK_NULL(issuedCertificate->data, ISSUER_NULL_PASSED);
+ CHECK_LESS_EQUAL(ISSUER_MAX_CERT_SIZE, issuedCertificate->len, ISSUER_WRONG_BYTE_ARRAY_LEN);
+
+ subjectName = OICCalloc(1, sizeof(UTF8String_t));
+ CHECK_NULL(subjectName, ISSUER_MEMORY_ALLOC_FAILED);
+
+ subjectPublicKey = OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(subjectPublicKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ subjectName->buf = uint8SubjectName;
+ subjectPublicKey->buf = uint8SubjectPublicKey;
+
+ CHECK_CALL(DecodeCSR, encodedCSR, subjectName, subjectPublicKey);
+
+ uint8SubjectName[subjectName->size] = '\0';
+ CHECK_CALL(CKMIssueDeviceCertificate, uint8SubjectName, 0, 0, uint8SubjectPublicKey + 1,
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ issuedCertificate);
+
+ FUNCTION_CLEAR(
+ OICFree(subjectPublicKey);
+ OICFree(subjectName);
+ );
+}
+
+PKIError CKMIssueCRL (const uint8_t *uint8ThisUpdateTime, const uint32_t numberOfRevoked,
+ const uint32_t *revokedNumbers, const uint8_t **revocationDates,
+ ByteArray *encodedCRL)
+{
+ FUNCTION_INIT();
+ BIT_STRING_t *issuerPrivateKey = NULL;
+ UTCTime_t *thisUpdateTime = NULL;
+ CertificateRevocationInfo_t *certificateRevocationInfo = NULL;
+ UTF8String_t *issuerName = NULL;
+ uint32_t i;
+
+ uint8_t caPrivateKey[PRIVATE_KEY_SIZE];
+ uint8_t uint8caName[ISSUER_MAX_NAME_SIZE];
+
+ ByteArray privKeyIss = BYTE_ARRAY_INITIALIZER;
+ ByteArray caName = BYTE_ARRAY_INITIALIZER;
+
+ CHECK_NULL(numberOfRevoked, ISSUER_NULL_PASSED);
+ CHECK_NULL(revokedNumbers, ISSUER_NULL_PASSED);
+ CHECK_NULL(revocationDates, ISSUER_NULL_PASSED);
+ CHECK_NULL(encodedCRL, ISSUER_NULL_PASSED);
+ CHECK_NULL(encodedCRL->data, ISSUER_NULL_PASSED);
+ CHECK_LESS_EQUAL((CRL_MIN_SIZE + numberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4)),
+ encodedCRL->len, ISSUER_WRONG_BYTE_ARRAY_LEN);
+
+ issuerPrivateKey = (BIT_STRING_t *)OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(issuerPrivateKey, ISSUER_MEMORY_ALLOC_FAILED);
+
+ thisUpdateTime = (UTCTime_t *)OICCalloc(1, sizeof(UTCTime_t));
+ CHECK_NULL(thisUpdateTime, ISSUER_MEMORY_ALLOC_FAILED);
+
+ issuerName = (UTF8String_t *)OICCalloc(1, sizeof(UTF8String_t));
+ CHECK_NULL(issuerName, ISSUER_MEMORY_ALLOC_FAILED);
+
+ certificateRevocationInfo = (CertificateRevocationInfo_t *)OICCalloc(numberOfRevoked,
+ sizeof(CertificateRevocationInfo_t));
+ CHECK_NULL(certificateRevocationInfo, ISSUER_MEMORY_ALLOC_FAILED);
+
+ privKeyIss.data = caPrivateKey;
+ privKeyIss.len = PRIVATE_KEY_SIZE;
+ caName.data = uint8caName;
+ caName.len = ISSUER_MAX_NAME_SIZE;
+
+ //allocate issuerPrivateKey
+ issuerPrivateKey->size = PRIVATE_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ issuerPrivateKey->buf = (uint8_t *)OICCalloc((issuerPrivateKey->size), sizeof(uint8_t));
+ CHECK_NULL(issuerPrivateKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(issuerPrivateKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+
+ //read CA private key from the CA storage
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAPrivateKey, &privKeyIss);
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((issuerPrivateKey->buf) + 1, privKeyIss.data, PRIVATE_KEY_SIZE);
+
+ //thisUpdateTime
+ if (uint8ThisUpdateTime)
+ {
+ thisUpdateTime->buf = (uint8_t *)uint8ThisUpdateTime;
+ }
+ else
+ {
+ thisUpdateTime->buf = (uint8_t *)ISSUER_DEFAULT_THIS_UPDATE;
+ }
+ thisUpdateTime->size = strlen((const char *)thisUpdateTime->buf);
+
+ //RootName
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAName, &caName);
+ issuerName->buf = caName.data;
+ issuerName->size = caName.len;
+
+ // CRI
+ for ( i = 0; i < numberOfRevoked; i++ )
+ {
+ certificateRevocationInfo[i].userCertificate = revokedNumbers[i];
+ certificateRevocationInfo[i].revocationDate.buf = (uint8_t *)revocationDates[i];
+ certificateRevocationInfo[i].revocationDate.size =
+ strlen((const char *)revocationDates[i]);
+ }
+
+ CHECK_CALL(GenerateCRL, issuerName, thisUpdateTime, numberOfRevoked, certificateRevocationInfo,
+ issuerPrivateKey, encodedCRL);
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(SetCertificateRevocationList, encodedCRL);
+ CHECK_CALL(SaveCKMInfo);
+
+ FUNCTION_CLEAR(
+ OICFree(issuerName);
+ OICFree(thisUpdateTime);
+ OICFree(certificateRevocationInfo);
+ ASN_STRUCT_FREE(asn_DEF_BIT_STRING, issuerPrivateKey);
+ );
+}
+
+PKIError CKMRevocateCertificate (const uint8_t *uint8ThisUpdateTime, const long revokedNumber,
+ ByteArray *encodedCRL)
+{
+ FUNCTION_INIT();
+ ByteArray oldCRL = BYTE_ARRAY_INITIALIZER;
+ asn_dec_rval_t rval; /* Decoder return value */
+ CertificateRevocationList_t *certificateRevocationList = NULL; // Type to decode
+ CertificateRevocationInfo_t *CRI = NULL;
+ long serialNumber = 0;
+ long numberOfRevoked = 0;
+ uint32_t crlMaxSize = 0;
+
+ BIT_STRING_t *issuerPrivateKey = NULL;
+ uint8_t caPrivateKey[PRIVATE_KEY_SIZE];
+ ByteArray privKeyIss = BYTE_ARRAY_INITIALIZER;
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetNumberOfRevoked, &numberOfRevoked);
+
+ crlMaxSize = (CRL_MIN_SIZE +
+ (numberOfRevoked + 1) * (sizeof(CertificateRevocationInfo_t) + 4));
+
+ CHECK_NULL(encodedCRL, ISSUER_NULL_PASSED);
+ CHECK_NULL(encodedCRL->data, ISSUER_NULL_PASSED);
+ CHECK_LESS_EQUAL(crlMaxSize, encodedCRL->len, ISSUER_WRONG_BYTE_ARRAY_LEN);
+
+ //obtain CRL
+ oldCRL.data = (uint8_t *)OICMalloc(crlMaxSize);
+ CHECK_NULL(oldCRL.data, ISSUER_MEMORY_ALLOC_FAILED);
+ oldCRL.len = crlMaxSize;
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCertificateRevocationList, &oldCRL);
+ CHECK_CALL(CloseCKMInfo);
+
+ //decode CRL
+ rval = ber_decode(0, &asn_DEF_CertificateRevocationList, (void **)&certificateRevocationList,
+ oldCRL.data, oldCRL.len);
+ CHECK_EQUAL(rval.code, RC_OK, ISSUER_CSR_DER_DECODE_FAIL);
+
+ //add one certificate into CRL
+ CRI = (CertificateRevocationInfo_t *)OICCalloc(1, sizeof(CertificateRevocationInfo_t));
+ CHECK_NULL(CRI, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ CRI->revocationDate.size = (int)strlen((const char *)uint8ThisUpdateTime);
+ CRI->revocationDate.buf = OICCalloc((CRI->revocationDate.size) + 1, sizeof(char));
+ //additional byte for \0 at the end
+ CHECK_NULL(CRI->revocationDate.buf, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ memcpy(CRI->revocationDate.buf, uint8ThisUpdateTime, CRI->revocationDate.size + 1);
+ //additional byte for \0 at the end
+
+ CRI->userCertificate = revokedNumber;
+ ASN_SEQUENCE_ADD((void *)(&(certificateRevocationList->
+ tbsCertList.revokedCertificates.list)), (void *)(CRI));
+
+ //prepare memory for issuerPrivateKey
+ issuerPrivateKey = (BIT_STRING_t *)OICCalloc(1, sizeof(BIT_STRING_t));
+ CHECK_NULL(issuerPrivateKey, ISSUER_MEMORY_ALLOC_FAILED);
+ privKeyIss.data = caPrivateKey;
+ privKeyIss.len = PRIVATE_KEY_SIZE;
+ //allocate issuerPrivateKey
+ issuerPrivateKey->size = PRIVATE_KEY_SIZE + 1; //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ issuerPrivateKey->buf = (uint8_t *)OICCalloc((issuerPrivateKey->size), sizeof(uint8_t));
+ CHECK_NULL(issuerPrivateKey->buf, ISSUER_MEMORY_ALLOC_FAILED);
+ *(issuerPrivateKey->buf) = (uint8_t)ASN1_UNCOMPRESSED_KEY_ID;
+
+ //read CA private key from the CA storage
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCAPrivateKey, &privKeyIss);
+
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ memcpy((issuerPrivateKey->buf) + 1, privKeyIss.data, PRIVATE_KEY_SIZE);
+
+ //SignCRL
+ CHECK_CALL(SignCRL, certificateRevocationList, crlMaxSize, issuerPrivateKey, encodedCRL);
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCRLSerialNumber, &serialNumber);
+ serialNumber++;
+ CHECK_CALL(SetCRLSerialNumber, &serialNumber);
+ numberOfRevoked++;
+ CHECK_CALL(SetNumberOfRevoked, &numberOfRevoked);
+ CHECK_CALL(SetCertificateRevocationList, encodedCRL);
+ CHECK_CALL(SaveCKMInfo);
+
+ FUNCTION_CLEAR(
+ ASN_STRUCT_FREE(asn_DEF_CertificateRevocationList, certificateRevocationList);
+ certificateRevocationList = NULL;
+
+ );
+}
+
+PKIError CKMGetCRL (ByteArray *certificateRevocationList)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(certificateRevocationList, ISSUER_NULL_PASSED);
+ CHECK_NULL(certificateRevocationList->data, ISSUER_NULL_PASSED);
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCertificateRevocationList, certificateRevocationList);
+ CHECK_CALL(CloseCKMInfo);
+
+ FUNCTION_CLEAR();
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#include "ckm_info.h"
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "cJSON.h"
+#include "base64.h"
+#include "psinterface.h"
+#include "srmresourcestrings.h"
+#include "crlresource.h"
+#include "crl_generator.h"
+
+//constants used in ckmInfo
+#define CKM_INFO_IS_NOT_LOADED (0)
+#define CKM_INFO_IS_LOADED (1)
+#define CA_PRIVATE_KEY_IS_NOT_SET (0)
+#define CA_PRIVATE_KEY_IS_SET (1)
+#define CA_PRIVATE_KEY_DEFAULT_VALUE (0)
+#define CA_PUBLIC_KEY_IS_NOT_SET (0)
+#define CA_PUBLIC_KEY_IS_SET (1)
+#define CA_PUBLIC_KEY_DEFAULT_VALUE (0)
+#define CA_CERTIFICATE_CHAIN_IS_NOT_SET (0)
+#define CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED (0)
+#define CA_NAME_IS_NOT_SET (0)
+#define CA_NAME_DEFAULT_VALUE (0)
+#define CERTIFICATE_SN_INITIAL_VALUE (1)
+#define CRL_SN_INITIAL_VALUE (1)
+#define NUMBER_OF_REVOKED_CERTIFICATES_INITIAL_VALUE (0)
+
+//constants used in crlInfo
+#define CRL_IS_NOT_SET (0)
+#define CRL_MEMORY_IS_NOT_ALLOCATED (0)
+
+static CKMInfo_t g_ckmInfo = {CKM_INFO_IS_NOT_LOADED,
+ CA_PRIVATE_KEY_IS_NOT_SET, {CA_PRIVATE_KEY_DEFAULT_VALUE},
+ CA_PUBLIC_KEY_IS_NOT_SET, {CA_PUBLIC_KEY_DEFAULT_VALUE},
+ CA_CERTIFICATE_CHAIN_IS_NOT_SET,
+ CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED,
+ CA_NAME_IS_NOT_SET, {CA_NAME_DEFAULT_VALUE},
+ CERTIFICATE_SN_INITIAL_VALUE, CRL_SN_INITIAL_VALUE,
+ NUMBER_OF_REVOKED_CERTIFICATES_INITIAL_VALUE};
+
+static OicSecCrl_t g_crlInfo = {CRL_IS_NOT_SET,
+ BYTE_ARRAY_INITIALIZER, BYTE_ARRAY_INITIALIZER};
+
+//General functions
+
+PKIError InitCKMInfo(void)
+{
+ FUNCTION_INIT();
+ FILE *filePointer = NULL;
+ int count = 1;
+ int objectsRead = 0;
+ int objectsWrote = 0;
+
+ if (!g_ckmInfo.CKMInfoIsLoaded)
+ {
+ filePointer = fopen(CA_STORAGE_FILE, "rb");
+ if (filePointer) //read existing storage
+ {
+ objectsRead = fread(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
+ g_ckmInfo.CACertificateChain = CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED;
+ CHECK_EQUAL(objectsRead, count, ISSUER_CA_STORAGE_FILE_READ_ERROR);
+ }
+ else ////create new storage
+ {
+ filePointer = fopen(CA_STORAGE_FILE, "wb");
+ CHECK_NULL(filePointer, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
+ objectsWrote = fwrite(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
+ CHECK_EQUAL(objectsWrote, count, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
+ }
+ CHECK_CALL(InitCRL);
+ CHECK_CALL(InitCRT);
+ g_ckmInfo.CKMInfoIsLoaded = CKM_INFO_IS_LOADED;
+ }
+ FUNCTION_CLEAR(
+ if (filePointer)
+ {
+ fclose(filePointer);
+ filePointer = NULL;
+ }
+ );
+}
+
+PKIError SaveCKMInfo(void)
+{
+ FUNCTION_INIT();
+ FILE *filePointer = NULL;
+ int count = 1;
+ int objectsWrote = 0;
+
+ CHECK_COND(g_ckmInfo.CKMInfoIsLoaded, CKM_INFO_IS_NOT_INIT);
+ filePointer = fopen(CA_STORAGE_FILE, "wb");
+ CHECK_NULL(filePointer, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
+ objectsWrote = fwrite(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
+ CHECK_EQUAL(objectsWrote, count, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
+ if ((g_crlInfo.CrlData.data)&&(g_crlInfo.CrlData.len))
+ {
+ CHECK_CALL(SaveCRL);
+ }
+ if (g_ckmInfo.CAChainLength)
+ {
+ CHECK_CALL(SaveCRT);
+ }
+ FUNCTION_CLEAR(
+ if (filePointer)
+ {
+ fclose(filePointer);
+ filePointer = NULL;
+ }
+ );
+}
+
+PKIError CloseCKMInfo(void)
+{
+ FUNCTION_INIT();
+ CHECK_CALL(SaveCKMInfo);
+ OICFree(g_crlInfo.CrlData.data);
+ g_crlInfo.CrlData.data = CRL_MEMORY_IS_NOT_ALLOCATED;
+ OICFree(g_crlInfo.ThisUpdate.data);
+ g_crlInfo.ThisUpdate.data = CRL_MEMORY_IS_NOT_ALLOCATED;
+ OICFree(g_ckmInfo.CACertificateChain);
+ g_ckmInfo.CACertificateChain = CA_CERTIFICATE_CHAIN_MEMORY_IS_NOT_ALLOCATED;
+ g_ckmInfo.CKMInfoIsLoaded = CKM_INFO_IS_NOT_LOADED;
+ g_crlInfo.CrlId = CRL_IS_NOT_SET;
+ FUNCTION_CLEAR();
+}
+
+PKIError SetCKMInfo (const long *nextSN, const long *CRLSerialNumber,
+ const ByteArray *CAPrivateKey, const ByteArray *CAPublicKey,
+ const ByteArray *CAName)
+{
+ FUNCTION_INIT();
+ if (nextSN)
+ CHECK_CALL(SetNextSerialNumber, nextSN);
+ if (CRLSerialNumber)
+ CHECK_CALL(SetCRLSerialNumber, CRLSerialNumber);
+ if (CAPrivateKey)
+ CHECK_CALL(SetCAPrivateKey, CAPrivateKey);
+ if (CAPublicKey)
+ CHECK_CALL(SetCAPublicKey, CAPublicKey);
+ if (CAName)
+ CHECK_CALL(SetCAName, CAName);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCKMInfo (long *nextSN, long *CRLSerialNumber,
+ ByteArray *CAPrivateKey, ByteArray *CAPublicKey,
+ ByteArray *CAName)
+{
+ FUNCTION_INIT();
+ if (nextSN)
+ CHECK_CALL(GetNextSerialNumber, nextSN);
+ if (CRLSerialNumber)
+ CHECK_CALL(GetCRLSerialNumber, CRLSerialNumber);
+ if (CAPrivateKey)
+ CHECK_CALL(GetCAPrivateKey, CAPrivateKey);
+ if (CAPublicKey)
+ CHECK_CALL(GetCAPublicKey, CAPublicKey);
+ if (CAName)
+ CHECK_CALL(GetCAName, CAName);
+
+ FUNCTION_CLEAR();
+}
+
+/*Private Key*/
+PKIError SetCAPrivateKey (const ByteArray *CAPrivateKey)
+{
+ FUNCTION_INIT();
+ CHECK_NULL_BYTE_ARRAY_PTR(CAPrivateKey, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_EQUAL(CAPrivateKey->len, PRIVATE_KEY_SIZE, ISSUER_CA_STORAGE_WRONG_PRIVATE_KEY_LEN);
+ memcpy(g_ckmInfo.CAPrivateKey, CAPrivateKey->data, PRIVATE_KEY_SIZE);
+ g_ckmInfo.CAPrivateKeyIsSet = CA_PRIVATE_KEY_IS_SET;
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCAPrivateKey (ByteArray *CAPrivateKey)
+{
+ FUNCTION_INIT();
+ CHECK_COND(g_ckmInfo.CAPrivateKeyIsSet, ISSUER_CA_STORAGE_PRIVATE_KEY_UNDEFINED);
+ CHECK_NULL_BYTE_ARRAY_PTR(CAPrivateKey, ISSUER_CA_STORAGE_NULL_PASSED);
+ memcpy(CAPrivateKey->data, g_ckmInfo.CAPrivateKey, PRIVATE_KEY_SIZE);
+ CAPrivateKey->len = PRIVATE_KEY_SIZE;
+
+ FUNCTION_CLEAR();
+}
+
+/*Public Key*/
+PKIError SetCAPublicKey (const ByteArray *CAPublicKey)
+{
+ FUNCTION_INIT();
+ CHECK_NULL_BYTE_ARRAY_PTR(CAPublicKey, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_EQUAL(CAPublicKey->len, PUBLIC_KEY_SIZE, ISSUER_CA_STORAGE_WRONG_PUBLIC_KEY_LEN);
+ memcpy(g_ckmInfo.CAPublicKey, CAPublicKey->data, PUBLIC_KEY_SIZE);
+ g_ckmInfo.CAPublicKeyIsSet = CA_PUBLIC_KEY_IS_SET;
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCAPublicKey (ByteArray *CAPublicKey)
+{
+ FUNCTION_INIT();
+ CHECK_COND(g_ckmInfo.CAPublicKeyIsSet, ISSUER_CA_STORAGE_PUBLIC_KEY_UNDEFINED);
+ CHECK_NULL_BYTE_ARRAY_PTR(CAPublicKey, ISSUER_CA_STORAGE_NULL_PASSED);
+ memcpy(CAPublicKey->data, g_ckmInfo.CAPublicKey, PUBLIC_KEY_SIZE);
+ CAPublicKey->len = PUBLIC_KEY_SIZE;
+
+ FUNCTION_CLEAR();
+}
+
+/*CAName*/
+PKIError SetCAName (const ByteArray *CAName)
+{
+ FUNCTION_INIT();
+ CHECK_NULL_BYTE_ARRAY_PTR(CAName, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_LESS_EQUAL(CAName->len, ISSUER_MAX_NAME_SIZE, ISSUER_CA_STORAGE_WRONG_CA_NAME_LEN);
+ memcpy(g_ckmInfo.CAName, CAName->data, CAName->len);
+ g_ckmInfo.CANameSize = CAName->len;
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCAName (ByteArray *CAName)
+{
+ FUNCTION_INIT();
+ CHECK_COND(g_ckmInfo.CANameSize, ISSUER_CA_STORAGE_CA_NAME_UNDEFINED);
+ CHECK_NULL_BYTE_ARRAY_PTR(CAName, ISSUER_CA_STORAGE_NULL_PASSED);
+ memcpy(CAName->data, g_ckmInfo.CAName, g_ckmInfo.CANameSize);
+ CAName->len = g_ckmInfo.CANameSize;
+
+ FUNCTION_CLEAR();
+}
+
+//Certificate-related functions
+
+#define CERT_LEN_PREFIX (3)
+#define BYTE_SIZE (8) //bits
+
+static void WriteCertPrefix(uint8_t *prefix, uint32_t certLen)
+{
+ for (size_t i = 0; i < CERT_LEN_PREFIX; ++i)
+ {
+ prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF;
+ }
+}
+
+static uint32_t ParseCertPrefix(uint8_t *prefix)
+{
+ uint32_t res = 0;
+ if(NULL != prefix)
+ {
+ for(int i=0; i < CERT_LEN_PREFIX; ++i)
+ {
+ res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
+ }
+ }
+ return res;
+}
+
+PKIError InitCRT(void)
+{
+ FUNCTION_INIT();
+ FILE *filePointer = NULL;
+ uint32_t objectsRead = 0;
+ uint8_t prefix[CERT_LEN_PREFIX] = {0};
+
+ if (g_ckmInfo.CAChainLength)
+ {
+ filePointer = fopen(CA_STORAGE_CRT_FILE, "rb");
+ CHECK_NULL(filePointer, ISSUER_CA_STORAGE_CRT_READ_ERROR);
+
+ g_ckmInfo.CACertificateChain =
+ (ByteArray *)OICMalloc(sizeof(ByteArray) * g_ckmInfo.CAChainLength);
+ CHECK_NULL(g_ckmInfo.CACertificateChain, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
+
+ for (int i = 0; i < g_ckmInfo.CAChainLength; i++)
+ {
+ objectsRead = fread(prefix, sizeof(uint8_t), CERT_LEN_PREFIX, filePointer);
+ CHECK_EQUAL(objectsRead, CERT_LEN_PREFIX, ISSUER_CA_STORAGE_CRT_READ_ERROR);
+ g_ckmInfo.CACertificateChain[i].len = ParseCertPrefix(prefix);
+
+ g_ckmInfo.CACertificateChain[i].data =
+ (uint8_t *)OICMalloc(g_ckmInfo.CACertificateChain[i].len);
+ CHECK_NULL(g_ckmInfo.CACertificateChain[i].data,
+ ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
+ objectsRead = fread(g_ckmInfo.CACertificateChain[i].data, sizeof(uint8_t),
+ g_ckmInfo.CACertificateChain[i].len, filePointer);
+ CHECK_EQUAL(objectsRead, g_ckmInfo.CACertificateChain[i].len,
+ ISSUER_CA_STORAGE_CRT_READ_ERROR);
+ }
+ }
+ FUNCTION_CLEAR(
+ if (filePointer)
+ {
+ fclose(filePointer);
+ filePointer = NULL;
+ }
+ );
+}
+
+PKIError SaveCRT(void)
+{
+ FUNCTION_INIT();
+ FILE *filePointer = NULL;
+ uint32_t objectsWrote = 0;
+ uint8_t prefix[CERT_LEN_PREFIX] = {0};
+
+ filePointer = fopen(CA_STORAGE_CRT_FILE, "wb");
+ CHECK_NULL(filePointer, ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
+
+ for (int i = 0; i < g_ckmInfo.CAChainLength; i++)
+ {
+ WriteCertPrefix(prefix, g_ckmInfo.CACertificateChain[i].len);
+ objectsWrote = fwrite(prefix, sizeof(uint8_t), CERT_LEN_PREFIX, filePointer);
+ CHECK_EQUAL(objectsWrote, CERT_LEN_PREFIX, ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
+ objectsWrote = fwrite(g_ckmInfo.CACertificateChain[i].data, sizeof(uint8_t),
+ g_ckmInfo.CACertificateChain[i].len, filePointer);
+ CHECK_EQUAL(objectsWrote, g_ckmInfo.CACertificateChain[i].len,
+ ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
+ }
+
+ FUNCTION_CLEAR(
+ if (filePointer)
+ {
+ fclose(filePointer);
+ filePointer = NULL;
+ }
+ );
+}
+
+/*Serial Number*/
+PKIError SetNextSerialNumber (const long *nextSN)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(nextSN, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_LESS_EQUAL(0, *nextSN, ISSUER_CA_STORAGE_WRONG_SERIAL_NUMBER);
+ g_ckmInfo.nextSerialNumber = *nextSN;
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetNextSerialNumber (long *nextSN)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(nextSN, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_NULL(g_ckmInfo.nextSerialNumber, ISSUER_CA_STORAGE_SN_UNDEFINED);
+ *nextSN = g_ckmInfo.nextSerialNumber;
+
+ FUNCTION_CLEAR();
+}
+
+/*CA Certificate Chain*/
+PKIError SetCAChain (const uint8_t CAChainLength, const ByteArray *CAChain)
+{
+ FUNCTION_INIT();
+ CHECK_NULL_BYTE_ARRAY_PTR(CAChain, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_NULL(CAChainLength, ISSUER_CA_STORAGE_NULL_PASSED);
+
+ OICFree(g_ckmInfo.CACertificateChain);
+ g_ckmInfo.CACertificateChain = NULL;
+ g_ckmInfo.CACertificateChain = (ByteArray *)OICMalloc(sizeof(ByteArray) * CAChainLength);
+ CHECK_NULL(g_ckmInfo.CACertificateChain, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
+
+ for (int i = 0; i < CAChainLength; i++)
+ {
+ g_ckmInfo.CACertificateChain[i].data = (uint8_t *)OICMalloc(CAChain[i].len);
+ CHECK_NULL(g_ckmInfo.CACertificateChain[i].data, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
+ memcpy(g_ckmInfo.CACertificateChain[i].data, CAChain[i].data, CAChain[i].len);
+ g_ckmInfo.CACertificateChain[i].len = CAChain[i].len;
+ }
+ g_ckmInfo.CAChainLength = CAChainLength;
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCAChain (uint8_t* CAChainLength, ByteArray *CAChain)
+{
+ FUNCTION_INIT();
+ CHECK_COND(g_ckmInfo.CAChainLength, ISSUER_CA_STORAGE_CA_CHAIN_LENGTH_UNDEFINED);
+ CHECK_NULL_BYTE_ARRAY_PTR(CAChain, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_NULL(CAChainLength, PKI_NULL_PASSED);
+
+ for (int i = 0; i < g_ckmInfo.CAChainLength; i++)
+ {
+ CHECK_LESS_EQUAL(g_ckmInfo.CACertificateChain[i].len, CAChain[i].len,
+ ISSUER_CA_STORAGE_WRONG_BYTE_ARRAY_LEN);
+ memcpy(CAChain[i].data, g_ckmInfo.CACertificateChain[i].data,
+ g_ckmInfo.CACertificateChain[i].len);
+ CAChain[i].len = g_ckmInfo.CACertificateChain[i].len;
+ }
+
+ *CAChainLength = g_ckmInfo.CAChainLength;
+
+ FUNCTION_CLEAR();
+}
+
+/*Certificate*/
+PKIError SetCACertificate (const ByteArray *CACertificate)
+{
+ FUNCTION_INIT();
+ CHECK_NULL_BYTE_ARRAY_PTR(CACertificate, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_CALL(SetCAChain, 1, CACertificate);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCACertificate (ByteArray *CACertificate)
+{
+ FUNCTION_INIT();
+ uint8_t i;
+ CHECK_NULL_BYTE_ARRAY_PTR(CACertificate, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_CALL(GetCAChain, &i, CACertificate);
+
+ FUNCTION_CLEAR();
+}
+//CRL-related functions
+
+PKIError InitCRL(void)
+{
+ FUNCTION_INIT();
+ g_crlInfo = *(OicSecCrl_t *)GetCRLResource();
+ CHECK_NULL(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_NULL(g_crlInfo.ThisUpdate.data, ISSUER_CA_STORAGE_NULL_PASSED);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError SaveCRL(void)
+{
+ FUNCTION_INIT();
+
+ CHECK_EQUAL(UpdateCRLResource(&g_crlInfo),
+ OC_STACK_OK, ISSUER_CA_STORAGE_CRL_WRITE_ERROR);
+ FUNCTION_CLEAR();
+}
+
+/*CRL Serial Number*/
+PKIError SetCRLSerialNumber (const long *CRLSerialNumber)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(CRLSerialNumber, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_LESS_EQUAL(0, *CRLSerialNumber, ISSUER_CA_STORAGE_WRONG_CRL_SERIAL_NUMBER);
+ g_ckmInfo.CRLSerialNumber = *CRLSerialNumber;
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCRLSerialNumber (long *CRLSerialNumber)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(CRLSerialNumber, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_NULL(g_ckmInfo.CRLSerialNumber, ISSUER_CA_STORAGE_CRL_SN_UNDEFINED);
+ *CRLSerialNumber = g_ckmInfo.CRLSerialNumber;
+
+ FUNCTION_CLEAR();
+}
+
+/*Revocation List*/
+PKIError SetCertificateRevocationList (const ByteArray *certificateRevocationList)
+{
+ FUNCTION_INIT();
+ CHECK_NULL_BYTE_ARRAY_PTR(certificateRevocationList, ISSUER_CA_STORAGE_NULL_PASSED);
+
+ OICFree(g_crlInfo.CrlData.data);
+ g_crlInfo.CrlData.data = CRL_MEMORY_IS_NOT_ALLOCATED;
+ g_crlInfo.CrlData.data = (uint8_t *)OICMalloc(certificateRevocationList->len + 1);
+ CHECK_NULL(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_MEMORY_ALLOC_FAILED);
+ memcpy(g_crlInfo.CrlData.data, certificateRevocationList->data, certificateRevocationList->len);
+ g_crlInfo.CrlData.len = certificateRevocationList->len;
+
+ g_crlInfo.CrlId ++;
+ CHECK_CALL(SaveCRL);
+
+ FUNCTION_CLEAR();
+}
+
+PKIError GetCertificateRevocationList (ByteArray *certificateRevocationList)
+{
+ FUNCTION_INIT();
+ CHECK_COND(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_CRL_UNDEFINED);
+ CHECK_NULL_BYTE_ARRAY_PTR(certificateRevocationList, ISSUER_CA_STORAGE_NULL_PASSED);
+ OicSecCrl_t *tmpCRL;
+ tmpCRL = (OicSecCrl_t *)GetCRLResource();
+ g_crlInfo.CrlId = tmpCRL->CrlId;
+ g_crlInfo.CrlData = tmpCRL->CrlData;
+ g_crlInfo.ThisUpdate = tmpCRL->ThisUpdate;
+
+ CHECK_LESS_EQUAL(g_crlInfo.CrlData.len, certificateRevocationList->len,
+ ISSUER_WRONG_BYTE_ARRAY_LEN);
+ memcpy(certificateRevocationList->data, g_crlInfo.CrlData.data, g_crlInfo.CrlData.len);
+ certificateRevocationList->len = g_crlInfo.CrlData.len;
+
+ FUNCTION_CLEAR(
+ OICFree(tmpCRL);
+ );
+}
+
+PKIError SetNumberOfRevoked (const long *numberOfRevoked)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(numberOfRevoked, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_LESS_EQUAL(0, *numberOfRevoked, ISSUER_CA_STORAGE_WRONG_CRL_SERIAL_NUMBER);
+ g_ckmInfo.numberOfRevoked = *numberOfRevoked;
+
+ FUNCTION_CLEAR();
+}
+PKIError GetNumberOfRevoked (long *numberOfRevoked)
+{
+ FUNCTION_INIT();
+ CHECK_NULL(numberOfRevoked, ISSUER_CA_STORAGE_NULL_PASSED);
+ CHECK_NULL(g_ckmInfo.numberOfRevoked, ISSUER_CA_STORAGE_CRL_SN_UNDEFINED);
+ *numberOfRevoked = g_ckmInfo.numberOfRevoked;
+
+ FUNCTION_CLEAR();
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+#include "crl_generator.h"
+#include "pki.h"
+#include "oic_malloc.h"
+#include "ckm_info.h"
+
+//ecdsa-with-SHA256 1.2.840.10045.4.3.2 [RFC5759]
+static const uint8_t g_ECDSA_WITH_SHA256_OID[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
+
+//commonName 2.5.4.3 [RFC2256]
+static const uint8_t g_COMMON_NAME_OID[] = {0x55, 0x04, 0x03};
+
+PKIError GenerateCRL (const UTF8String_t *issuerName,
+ const UTCTime_t *thisUpdateTime, const uint32_t nuberOfRevoked,
+ const CertificateRevocationInfo_t *certificateRevocationInfo,
+ const BIT_STRING_t *issuerPrivateKey, ByteArray *encodedCRL)
+{
+ FUNCTION_INIT();
+
+ CertificateRevocationList_t *certificateRevocationList = NULL; /* Type to encode */
+ AttributeTypeAndValue_t *issuerTypeAndValue = NULL;
+ RelativeDistinguishedName_t *issuerRDN = NULL;
+ CertificateRevocationInfo_t *cri = NULL;
+
+ uint32_t crlMaxSize = (CRL_MIN_SIZE +
+ nuberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4));
+
+ uint32_t i;
+ long serialNumber = 0;
+
+ CHECK_NULL(issuerName, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(thisUpdateTime, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(certificateRevocationInfo, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(issuerPrivateKey, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(encodedCRL, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(encodedCRL->data, ISSUER_CRL_NULL_PASSED);
+ CHECK_LESS_EQUAL(crlMaxSize, encodedCRL->len, ISSUER_CRL_WRONG_BYTE_ARRAY_LEN);
+
+ /* Allocate the memory */
+ certificateRevocationList = OICCalloc(1, sizeof(CertificateRevocationList_t));//not malloc!
+ CHECK_NULL(certificateRevocationList, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ issuerTypeAndValue = OICCalloc(1, sizeof(AttributeTypeAndValue_t));
+ CHECK_NULL(issuerTypeAndValue, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ issuerRDN = OICCalloc(1, sizeof(RelativeDistinguishedName_t));
+ CHECK_NULL(issuerRDN, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ //set subject name
+ issuerTypeAndValue->value = *issuerName;
+ issuerTypeAndValue->type.buf = (uint8_t *)g_COMMON_NAME_OID; //2.5.4.3
+ issuerTypeAndValue->type.size = sizeof(g_COMMON_NAME_OID) / sizeof(g_COMMON_NAME_OID[0]);
+ ASN_SET_ADD(issuerRDN, issuerTypeAndValue);
+ ASN_SEQUENCE_ADD(&(certificateRevocationList->tbsCertList.issuer), issuerRDN);
+
+ //set signature algorithm
+ certificateRevocationList->signatureAlgorithm.algorithm.buf =
+ (uint8_t *)g_ECDSA_WITH_SHA256_OID; //1.2.840.10045.4.3.2
+ certificateRevocationList->signatureAlgorithm.algorithm.size =
+ sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
+ certificateRevocationList->signatureAlgorithm.nul = OICCalloc(1, sizeof(NULL_t));
+ CHECK_NULL(certificateRevocationList->signatureAlgorithm.nul,
+ ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ //set signature algorithm in TBS part
+ certificateRevocationList->tbsCertList.signature.algorithm.buf =
+ (uint8_t *)g_ECDSA_WITH_SHA256_OID; //1.2.840.10045.4.3.2
+ certificateRevocationList->tbsCertList.signature.algorithm.size =
+ sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
+ certificateRevocationList->tbsCertList.signature.nul = OICCalloc(1, sizeof(NULL_t));
+ CHECK_NULL(certificateRevocationList->tbsCertList.signature.nul,
+ ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ //set thisUpdateTime
+ certificateRevocationList->tbsCertList.thisUpdate = *thisUpdateTime;
+
+ //add revoked info
+ for ( i = 0; i < nuberOfRevoked; i++)
+ {
+ cri = OICCalloc(1, sizeof(CertificateRevocationInfo_t));
+ CHECK_NULL(cri, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ cri->revocationDate.size = (certificateRevocationInfo + i)->revocationDate.size;
+ cri->revocationDate.buf = OICCalloc((cri->revocationDate.size) + 1, sizeof(char));
+ CHECK_NULL(cri->revocationDate.buf, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ memcpy(cri->revocationDate.buf, (certificateRevocationInfo + i)->revocationDate.buf,
+ cri->revocationDate.size + 1);
+ cri->userCertificate = (certificateRevocationInfo + i)->userCertificate;
+ ASN_SEQUENCE_ADD((void *)(&(certificateRevocationList->
+ tbsCertList.revokedCertificates.list)), (void *)(cri));
+ }
+
+ CHECK_CALL(SignCRL, certificateRevocationList, crlMaxSize, issuerPrivateKey, encodedCRL);
+
+ CHECK_CALL(InitCKMInfo);
+ CHECK_CALL(GetCRLSerialNumber, &serialNumber);
+ serialNumber++;
+ CHECK_CALL(SetCRLSerialNumber, &serialNumber);
+ CHECK_CALL(SetNumberOfRevoked, (const long *)&nuberOfRevoked);
+ CHECK_CALL(SaveCKMInfo);
+
+ FUNCTION_CLEAR(
+ if (issuerTypeAndValue)
+ {
+ issuerTypeAndValue->value.buf = NULL;
+ issuerTypeAndValue->type.buf = NULL;
+ }
+ if (certificateRevocationList)
+ {
+ certificateRevocationList->tbsCertList.signature.algorithm.buf = NULL;
+ certificateRevocationList->signatureAlgorithm.algorithm.buf = NULL;
+ certificateRevocationList->tbsCertList.thisUpdate.buf = NULL;
+ }
+
+ ASN_STRUCT_FREE(asn_DEF_CertificateRevocationList, certificateRevocationList);
+ certificateRevocationList = NULL;
+ );
+}
+
+PKIError SignCRL(CertificateRevocationList_t *certificateRevocationList,
+ const uint32_t crlMaxSize, const BIT_STRING_t *issuerPrivateKey,
+ ByteArray *encodedCRL)
+{
+ FUNCTION_INIT();
+ uint8_t *crlInfoInDER = NULL;
+ asn_enc_rval_t ec; /* Encoder return value */
+ uint8_t *uint8Pointer = NULL;
+ ByteArray tbs = BYTE_ARRAY_INITIALIZER;
+ uint8_t signature[SIGN_FULL_SIZE];
+ uint8_t sha256[SHA_256_HASH_LEN];
+
+ CHECK_NULL(certificateRevocationList, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(crlMaxSize, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(issuerPrivateKey, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(encodedCRL, ISSUER_CRL_NULL_PASSED);
+ CHECK_NULL(encodedCRL->data, ISSUER_CRL_NULL_PASSED);
+ CHECK_LESS_EQUAL(crlMaxSize, encodedCRL->len, ISSUER_CRL_WRONG_BYTE_ARRAY_LEN);
+
+ //encode TBS to DER
+ crlInfoInDER = OICCalloc(1, crlMaxSize);
+ CHECK_NULL(crlInfoInDER, ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+
+ ec = der_encode_to_buffer(&asn_DEF_TBSCertList, &(certificateRevocationList->tbsCertList),
+ crlInfoInDER, crlMaxSize);
+
+ //sign CRL
+ CHECK_COND(ec.encoded > 0, ISSUER_CRL_ENCODER_DER_ENCODE_FAIL);
+ tbs.len = ec.encoded;
+ tbs.data = crlInfoInDER;
+ GET_SHA_256(tbs, sha256);
+ CHECK_COND(uECC_sign((issuerPrivateKey->buf) + 1, sha256, signature),
+ ISSUER_CRL_ENCODER_SIGNATURE_FAIL);
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+
+ // ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } (RFC 5480)
+ certificateRevocationList->signatureValue.size = SIGN_FULL_SIZE + 6;
+ // size for SEQUENCE ID + 2 * INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[0] > 127)
+ {
+ certificateRevocationList->signatureValue.size ++;
+ }
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[SIGN_R_LEN] > 127)
+ {
+ certificateRevocationList->signatureValue.size ++;
+ }
+ OICFree(certificateRevocationList->signatureValue.buf);
+ certificateRevocationList->signatureValue.buf = (uint8_t *)OICCalloc(
+ certificateRevocationList->signatureValue.size, sizeof(uint8_t));
+ CHECK_NULL(certificateRevocationList->signatureValue.buf,
+ ISSUER_CRL_ENCODER_MEMORY_ALLOC_FAILED);
+ *(certificateRevocationList->signatureValue.buf) = (12 << 2); //ASN.1 SEQUENCE ID
+ *(certificateRevocationList->signatureValue.buf + 1) =
+ certificateRevocationList->signatureValue.size - 2; //ASN.1 SEQUENCE size
+
+ uint8Pointer = certificateRevocationList->signatureValue.buf + 2; //skip SEQUENCE ID and size
+ *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[0] > 127)
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN + 1; //ASN.1 INTEGER size
+ uint8Pointer += 3; //skip INTEGER ID and size
+ }
+ else
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN; //ASN.1 INTEGER size
+ uint8Pointer += 2; //skip INTEGER ID and size
+ }
+ memcpy(uint8Pointer, signature, SIGN_R_LEN);
+
+ uint8Pointer += SIGN_R_LEN;
+ *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature [SIGN_R_LEN] > 127)
+ {
+ *(uint8Pointer + 1) = SIGN_S_LEN + 1; //ASN.1 INTEGER size
+ uint8Pointer += 3; //skip INTEGER ID and size
+ }
+ else
+ {
+ *(uint8Pointer + 1) = SIGN_S_LEN; //ASN.1 INTEGER size
+ uint8Pointer += 2; //skip INTEGER ID and size
+ }
+ memcpy(uint8Pointer, signature + SIGN_R_LEN, SIGN_S_LEN);
+
+ ec = der_encode_to_buffer(&asn_DEF_CertificateRevocationList, certificateRevocationList,
+ encodedCRL->data, crlMaxSize);
+ CHECK_COND(ec.encoded > 0, ISSUER_CRL_ENCODER_DER_ENCODE_FAIL);
+ encodedCRL->len = ec.encoded;
+
+ FUNCTION_CLEAR(
+ OICFree(crlInfoInDER);
+ crlInfoInDER = NULL;
+ );
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 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
+ *
+ * LICENSE-2.0" target="_blank">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.
+ *
+
+ ******************************************************************/
+
+
+#include "csr_generator.h"
+#include "pki.h"
+#include "oic_malloc.h"
+
+//ecdsa-with-SHA256 1.2.840.10045.4.3.2 [RFC5759]
+static const uint8_t g_ECDSA_WITH_SHA256_OID[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
+
+//Elliptic Curve Digital Signature Algorithm (ECDSA) 1.2.840.10045.2.1 [RFC7250]
+static const uint8_t g_EC_PUBLIC_KEY_OID[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01};
+
+//secp256r1 1.2.840.10045.3.1.7 [RFC5656]
+static const uint8_t g_PRIME_256_V1_OID[] = {0x2A, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
+
+//commonName 2.5.4.3 [RFC2256]
+static const uint8_t g_COMMON_NAME_OID[] = {0x55, 0x04, 0x03};
+
+PKIError EncodeCSR (const UTF8String_t *subjectName,
+ const BIT_STRING_t *subjectPublicKey,
+ const BIT_STRING_t *subjectPrivateKey,
+ ByteArray *encodedCSR)
+{
+ FUNCTION_INIT();
+ asn_enc_rval_t ec; /* Encoder return value */
+ CertificationRequest_t *certificationRequest = NULL; /* Type to encode */
+ AttributeTypeAndValue_t *subjTypeAndValue = NULL;
+ RelativeDistinguishedName_t *subjRDN = NULL;
+ uint8_t *uint8Pointer = NULL;
+ ByteArray tbs = BYTE_ARRAY_INITIALIZER;
+ uint8_t signature[SIGN_FULL_SIZE];
+ uint8_t sha256[SHA_256_HASH_LEN];
+ uint8_t ReqInfoInDER[CSR_MAX_SIZE];
+
+ CHECK_NULL(subjectName, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(subjectPublicKey, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(subjectPrivateKey, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(encodedCSR, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(encodedCSR->data, ISSUER_CSR_NULL_PASSED);
+ CHECK_LESS_EQUAL(CSR_MAX_SIZE, encodedCSR->len, ISSUER_CSR_WRONG_BYTE_ARRAY_LEN);
+
+ /* Allocate the memory */
+ certificationRequest = OICCalloc(1, sizeof(CertificationRequest_t)); // not malloc!
+ CHECK_NULL(certificationRequest, ISSUER_CSR_MEMORY_ALLOC_FAILED);
+
+ subjTypeAndValue = OICCalloc(1, sizeof(AttributeTypeAndValue_t));
+ CHECK_NULL(subjTypeAndValue, ISSUER_CSR_MEMORY_ALLOC_FAILED);
+
+ subjRDN = OICCalloc(1, sizeof(RelativeDistinguishedName_t));
+ CHECK_NULL(subjRDN, ISSUER_CSR_MEMORY_ALLOC_FAILED);
+
+ //set subject name
+ subjTypeAndValue->value = *subjectName;
+ subjTypeAndValue->type.buf = (uint8_t *)g_COMMON_NAME_OID; //2.5.4.3
+ subjTypeAndValue->type.size = sizeof(g_COMMON_NAME_OID) / sizeof(g_COMMON_NAME_OID[0]);
+ ASN_SET_ADD(subjRDN, subjTypeAndValue);
+ ASN_SEQUENCE_ADD(&(certificationRequest->certificationRequestInfo.subject), subjRDN);
+
+ //set version 0
+ certificationRequest->certificationRequestInfo.version = CSR_DEFAULT_VERSION;
+
+ //set signature algorithm
+ certificationRequest->signatureAlgorithm.algorithm.buf =
+ (uint8_t *)g_ECDSA_WITH_SHA256_OID; //1.2.840.10045.4.3.2
+ certificationRequest->signatureAlgorithm.algorithm.size =
+ sizeof(g_ECDSA_WITH_SHA256_OID) / sizeof(g_ECDSA_WITH_SHA256_OID[0]);
+ certificationRequest->signatureAlgorithm.nul = OICCalloc(1, sizeof(NULL_t));
+ CHECK_NULL(certificationRequest->signatureAlgorithm.nul, ISSUER_CSR_MEMORY_ALLOC_FAILED);
+
+ //set subject Public Key algorithm
+ certificationRequest->certificationRequestInfo.subjectPKInfo.algorithm.algorithm.buf =
+ (uint8_t *)g_EC_PUBLIC_KEY_OID; //1.2.840.10045.2.1
+ certificationRequest->certificationRequestInfo.subjectPKInfo.algorithm.algorithm.size =
+ sizeof(g_EC_PUBLIC_KEY_OID) / sizeof(g_EC_PUBLIC_KEY_OID[0]);
+
+ //set subject Public Key curve
+ certificationRequest->certificationRequestInfo.subjectPKInfo.algorithm.id_ecPublicKey =
+ OICCalloc(1, sizeof(OBJECT_IDENTIFIER_t));
+ CHECK_NULL(certificationRequest->
+ certificationRequestInfo.subjectPKInfo.algorithm.id_ecPublicKey,
+ ISSUER_CSR_MEMORY_ALLOC_FAILED);
+
+ certificationRequest->certificationRequestInfo.subjectPKInfo.algorithm.id_ecPublicKey->buf =
+ (uint8_t *)g_PRIME_256_V1_OID; //1.2.840.10045.3.1.7
+ certificationRequest->certificationRequestInfo.subjectPKInfo.algorithm.id_ecPublicKey->size =
+ sizeof(g_PRIME_256_V1_OID) / sizeof(g_PRIME_256_V1_OID[0]);
+
+ //set subject Public Key
+ certificationRequest->certificationRequestInfo.subjectPKInfo.subjectPublicKey =
+ *subjectPublicKey;
+
+ //encode TBS to DER
+ ec = der_encode_to_buffer(&asn_DEF_CertificationRequestInfo,
+ &(certificationRequest->certificationRequestInfo),
+ ReqInfoInDER, CSR_MAX_SIZE);
+ CHECK_COND(ec.encoded > 0, ISSUER_CSR_DER_ENCODE_FAIL);
+ tbs.len = ec.encoded;
+ tbs.data = ReqInfoInDER;
+ GET_SHA_256(tbs, sha256);
+ CHECK_COND(uECC_sign((subjectPrivateKey->buf) + 1, sha256, signature),
+ ISSUER_CSR_SIGNATURE_FAIL);
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+
+ // ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } (RFC 5480)
+ certificationRequest->signature.size = SIGN_FULL_SIZE + 6;
+ // size for SEQUENCE ID + 2 * INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[0] > 127)
+ {
+ certificationRequest->signature.size ++;
+ }
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[SIGN_R_LEN] > 127)
+ {
+ certificationRequest->signature.size ++;
+ }
+ certificationRequest->signature.buf = OICCalloc(certificationRequest->signature.size,
+ sizeof(uint8_t));
+ CHECK_NULL(certificationRequest->signature.buf, ISSUER_CSR_MEMORY_ALLOC_FAILED);
+ *(certificationRequest->signature.buf) = (12 << 2); //ASN.1 SEQUENCE ID
+ *(certificationRequest->signature.buf + 1) = certificationRequest->signature.size - 2;
+ //ASN.1 SEQUENCE size
+
+ uint8Pointer = certificationRequest->signature.buf + 2; //skip SEQUENCE ID and size
+ *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature[0] > 127)
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN + 1; //ASN.1 INTEGER size
+ uint8Pointer += 3; //skip INTEGER ID and size
+ }
+ else
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN; //ASN.1 INTEGER size
+ uint8Pointer += 2; //skip INTEGER ID and size
+ }
+ memcpy(uint8Pointer, signature, SIGN_R_LEN);
+
+ uint8Pointer += SIGN_R_LEN;
+ *uint8Pointer = (2 << 0); //ASN.1 INTEGER ID
+
+ // if first byte of positive INTEGER exceed 127 add 0 byte before
+ if (signature [SIGN_R_LEN] > 127)
+ {
+ *(uint8Pointer + 1) = SIGN_R_LEN + 1; //ASN.1 INTEGER size
+ uint8Pointer += 3; //skip INTEGER ID and size
+ }
+ else
+ {
+ *(uint8Pointer + 1) = SIGN_S_LEN; //ASN.1 INTEGER size
+ uint8Pointer += 2; //skip INTEGER ID and size
+ }
+ memcpy(uint8Pointer, signature + SIGN_R_LEN, SIGN_S_LEN);
+
+ ec = der_encode_to_buffer(&asn_DEF_CertificationRequest, certificationRequest,
+ encodedCSR->data, CSR_MAX_SIZE);
+ CHECK_COND(ec.encoded > 0, ISSUER_CSR_DER_ENCODE_FAIL);
+ encodedCSR->len = ec.encoded;
+
+ FUNCTION_CLEAR(
+ if (subjTypeAndValue)
+ {
+ subjTypeAndValue->value.buf = NULL;
+ subjTypeAndValue->type.buf = NULL;
+ }
+ if (certificationRequest)
+ {
+ certificationRequest->
+ certificationRequestInfo.subjectPKInfo.algorithm.algorithm.buf = NULL;
+
+ certificationRequest->signatureAlgorithm.algorithm.buf = NULL;
+
+ if (certificationRequest->
+ certificationRequestInfo.subjectPKInfo.algorithm.id_ecPublicKey)
+ {
+ certificationRequest->
+ certificationRequestInfo.subjectPKInfo.algorithm.id_ecPublicKey->buf = NULL;
+ }
+ }
+ ASN_STRUCT_FREE(asn_DEF_CertificationRequest, certificationRequest);
+ certificationRequest = NULL;
+ );
+}
+
+PKIError DecodeCSR (const ByteArray *encodedCSR,
+ UTF8String_t *subjectName, BIT_STRING_t *subjectPublicKey)
+{
+ FUNCTION_INIT();
+ asn_dec_rval_t rval; /* Decoder return value */
+ asn_enc_rval_t ec; /* Encoder return value */
+ CertificationRequest_t *certificationRequest = NULL; // Type to decode
+ ByteArray tbs = BYTE_ARRAY_INITIALIZER;
+ uint8_t sha256[SHA_256_HASH_LEN];
+ uint8_t ReqInfoInDER[CSR_MAX_SIZE];
+ uint8_t signature[SIGN_FULL_SIZE];
+
+ CHECK_NULL(encodedCSR, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(encodedCSR->data, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(subjectName, ISSUER_CSR_NULL_PASSED);
+ CHECK_NULL(subjectPublicKey, ISSUER_CSR_NULL_PASSED);
+
+ rval = ber_decode(0, &asn_DEF_CertificationRequest, (void **)&certificationRequest,
+ encodedCSR->data, encodedCSR->len);
+ CHECK_EQUAL(rval.code, RC_OK, ISSUER_CSR_DER_DECODE_FAIL);
+
+ //encode TBS to DER
+ ec = der_encode_to_buffer(&asn_DEF_CertificationRequestInfo,
+ &(certificationRequest->certificationRequestInfo),
+ ReqInfoInDER, CSR_MAX_SIZE);
+ CHECK_COND(ec.encoded > 0, ISSUER_CSR_DER_ENCODE_FAIL);
+ tbs.len = ec.encoded;
+ tbs.data = ReqInfoInDER;
+ GET_SHA_256(tbs, sha256);
+
+ // ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } (RFC 5480)
+ if (*(certificationRequest->signature.buf + 3) > SIGN_R_LEN) //check length of first INTEGER (r)
+ {
+ //move to start of second INTEGER (s)
+ memcpy(signature, certificationRequest->signature.buf + 5, SIGN_R_LEN);
+ }
+ else
+ {
+ //move to start of second INTEGER (s)
+ memcpy(signature, certificationRequest->signature.buf + 4, SIGN_R_LEN);
+ }
+ memcpy((signature + SIGN_R_LEN),
+ (certificationRequest->signature.buf +
+ certificationRequest->signature.size - SIGN_S_LEN), SIGN_S_LEN);
+ //verify signature
+ CHECK_COND(uECC_verify(certificationRequest->
+ certificationRequestInfo.subjectPKInfo.subjectPublicKey.buf + 1,
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+ sha256, signature), ISSUER_CSR_INVALID_SIGNATURE);
+
+ subjectName->size =
+ certificationRequest->certificationRequestInfo.subject.list.array[0]->
+ list.array[0]->value.size;
+ CHECK_LESS_EQUAL(subjectName->size, CSR_MAX_NAME_SIZE, ISSUER_CSR_TOO_LONG_NAME);
+ memcpy(subjectName->buf,
+ certificationRequest->certificationRequestInfo.subject.list.array[0]->
+ list.array[0]->value.buf, subjectName->size);
+
+ subjectPublicKey->size =
+ certificationRequest->certificationRequestInfo.subjectPKInfo.subjectPublicKey.size;
+ CHECK_EQUAL(subjectPublicKey->size, PUBLIC_KEY_SIZE + 1, ISSUER_CSR_INVALID_KEY_FORMAT);
+ //additional byte for ASN1_UNCOMPRESSED_KEY_ID
+
+ memcpy(subjectPublicKey->buf,
+ certificationRequest->certificationRequestInfo.subjectPKInfo.subjectPublicKey.buf,
+ subjectPublicKey->size);
+
+ FUNCTION_CLEAR(
+ ASN_STRUCT_FREE(asn_DEF_CertificationRequest, certificationRequest);
+ );
+}