implement validation tools for CK manager
authorOleksandr Dmytrenko <o.dmytrenko@samsung.com>
Thu, 24 Sep 2015 13:44:15 +0000 (16:44 +0300)
committerSachin Agrawal <sachin.agrawal@intel.com>
Sat, 3 Oct 2015 03:41:36 +0000 (03:41 +0000)
[Pathc Set 6]: added getopt parser
[Patch Set 7]: code astyled
[Patch Set 8]: initialization fixed
[Patch Set 11]: add init macros
[Patch Set 13]: comments(clear)
[Patch Set 13-]: replace malloc to OICMalloc

Change-Id: Ifb2ac78454de87ff7f82aedeb1dbfaae8d20f372
Signed-off-by: Oleksii Udod <o.udod@samsung.com>
Signed-off-by: Oleksandr Dmytrenko <o.dmytrenko@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2448
Reviewed-by: Sachin Agrawal <sachin.agrawal@intel.com>
Reviewed-by: dongik Lee <dongik.lee@samsung.com>
Tested-by: Sachin Agrawal <sachin.agrawal@intel.com>
(cherry picked from commit abb0f6000a00e7c1fb32204a0939deeb4cf48bbe)
Reviewed-on: https://gerrit.iotivity.org/gerrit/3431
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
resource/csdk/connectivity/inc/pkix/byte_array.h
resource/csdk/connectivity/inc/pkix/cert.h
resource/csdk/security/provisioning/ck_manager/SConscript
resource/csdk/security/provisioning/ck_manager/tools/x509_check.c [new file with mode: 0644]
resource/csdk/security/provisioning/ck_manager/tools/x509_issue.c [new file with mode: 0644]

index 22892cd..dd50893 100644 (file)
@@ -19,7 +19,6 @@
 
  ******************************************************************/
 
-
 #ifndef _BYTE_ARRAY_H_
 #define _BYTE_ARRAY_H_
 
@@ -46,14 +45,14 @@ typedef struct
 } ByteArray;
 
 
-/**@def BYTE_ARRAY_INITIALIZER
+/**
  *
  * Initializes of existing byte array pointer to \a NULL.
  */
 #undef BYTE_ARRAY_INITIALIZER
 #define BYTE_ARRAY_INITIALIZER {NULL, 0}
 
-/**@def INIT_BYTE_ARRAY(array)
+/**
  *
  * Initializes of existing byte array \a array.
  *
@@ -65,7 +64,7 @@ typedef struct
         (array).len = 0;            \
     }while(0)
 
-/**@def PRINT_BYTE_ARRAY(msg, array)
+/**
  *
  * Prints out byte array \a array in hex representation with message \a msg.
  *
@@ -83,7 +82,7 @@ typedef struct
         putchar('\n');                                  \
     }while(0)
 
-/**@def INC_BYTE_ARRAY_PTR(array, size)
+/**
  *
  * Increments byte array pointer \a array by \a size.
  *
@@ -96,7 +95,7 @@ typedef struct
         (array)->len -= size;                    \
     }while(0)
 
-/**@def INC_BYTE_ARRAY(array, size)
+/**
  *
  * Increments byte array \a array by \a size.
  *
@@ -109,6 +108,20 @@ typedef struct
         (array).len -= size;                 \
     }while(0)
 
+/**
+ *
+ * Initializes of existing byte array.
+ *
+ * @param array of uint8_t
+ *
+ * @note Array must  be statically allocated.
+ */
+#ifdef __cplusplus
+#define BYTE_ARRAY_CONSTRUCTOR(array) {array, sizeof(array)}
+#else
+#define BYTE_ARRAY_CONSTRUCTOR(array) {.data = array, .len = sizeof(array)}
+#endif
+
 #ifdef __cplusplus
 }
 #endif //__cplusplus
index 03c6f7c..1c6a39f 100644 (file)
@@ -54,6 +54,23 @@ typedef struct
 } CertificateX509;
 
 /**
+ *
+ *
+ * Initializes of certificate structure.
+ *
+ */
+#define CERTIFICATE_X509_INITIALIZER {\
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER,                                            \
+    BYTE_ARRAY_INITIALIZER}
+
+/**
  * Reads certificate from byte array and write it into certificate structure.
  *
  * @param[in] code  Byte array with DER encoded certificate
index a473e5e..00e2cbe 100644 (file)
@@ -46,5 +46,6 @@ x509_env.AppendUnique(LIBS = ['asn1'])
 x509_env.AppendUnique(LIBS = ['Base64'])
 x509_env.AppendUnique(LIBS = ['Json'])
 
+SConscript('tools/SConscript')
 SConscript('sample/SConscript')
 SConscript('unittest/SConscript')
diff --git a/resource/csdk/security/provisioning/ck_manager/tools/x509_check.c b/resource/csdk/security/provisioning/ck_manager/tools/x509_check.c
new file mode 100644 (file)
index 0000000..bb63292
--- /dev/null
@@ -0,0 +1,197 @@
+/******************************************************************
+ *
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <getopt.h>
+
+#include "byte_array.h"
+#include "pki_errors.h"
+#include "pki.h"
+#include "crl.h"
+#include "oic_malloc.h"
+
+#define SUCCESS_RES            0
+#define FAIL_RES               1
+
+const char COMMAND_CRT[] = "crt";
+const char COMMAND_CRL[] = "crl";
+
+/**
+ * Shows program usage hint.
+ */
+void Usage()
+{
+    printf("Use next command:\n");
+    printf("x509_check -c <crt/crl> -f <path to crt/crl file> -s <path to CA certificate>\n");
+    printf("\t[-c]\t command name crt | crl\n");
+    printf("\t[-f]\t path to crt/crl file\n");
+    printf("\t[-s]\t path to CA certificate>\n");
+}
+
+/**
+ * Converts DER file to byte array.
+ *
+ * @param[in]  filePath - path to DER file (Certificate or CRL)
+ * @param[out] caPublicKey - ByteArray with DER encoded CRT or CRL
+ */
+void FileToByteArray(const char *filePath, ByteArray *out)
+{
+    if (!filePath)
+    {
+        printf("File path is NULL!\n");
+        exit(0);
+    }
+
+    FILE *inFile = fopen(filePath, "rb");
+
+    if (!inFile)
+    {
+        printf("Specified file doesn't exist!\n");
+        exit(0);
+    }
+
+    fseek(inFile, 0, SEEK_END);
+    out->len = ftell(inFile);
+    rewind(inFile);
+    out->data = (uint8_t *)OICMalloc(out->len);
+
+    if (!out->data)
+    {
+        printf("Impossible to allocate memory!\n");
+        exit(0);
+    }
+
+    if (!fread(out->data, sizeof(uint8_t), out->len, inFile))
+    {
+        printf("No info in file!\n");
+        exit(0);
+    }
+    fclose(inFile);
+}
+
+/**
+ * Main function.
+ *
+ * Checks certificate and certificate revocation list
+ *
+ * @param[in]  argc An integer argument count of the command line arguments
+ * @param[in]  argv An argument vector of the command line arguments
+ *
+ * @return[out] an integer 0 upon exit success
+ */
+int main(int argc, char *argv[])
+{
+    int isCrt = 0;
+    const char *testedFileName = 0;
+    const char *caCrtFileName = 0;
+
+    // Parse command line arguments
+    int opt;
+
+    while ((opt = getopt(argc, argv, "c:f:s:")) != -1)
+    {
+        switch (opt)
+        {
+            case 'c':
+                if (!strcmp(COMMAND_CRT, optarg))
+                {
+                    isCrt = 1;
+                }
+                else if (!strcmp(COMMAND_CRL, optarg))
+                {
+                    isCrt = 0;
+                }
+                else
+                {
+                    printf("Wrong command(-c)!\n");
+                    Usage();
+                    exit(0);
+                }
+                break;
+            case 'f':
+                testedFileName = optarg;
+                break;
+            case 's':
+                caCrtFileName = optarg;
+                break;
+            default:
+                Usage();
+                exit(0);
+        }
+    }
+
+    if (testedFileName == NULL || caCrtFileName == NULL)
+    {
+        printf("Wrong file name\n");
+        Usage();
+        exit(0);
+    }
+
+    // main
+    ByteArray testedCrtCrl = BYTE_ARRAY_INITIALIZER; // Could contain either Certificate or CRL
+    ByteArray caCrt = BYTE_ARRAY_INITIALIZER;
+
+    // Copy DER files, specified in command line to ByteArray structure
+    FileToByteArray(testedFileName, &testedCrtCrl);
+    FileToByteArray(caCrtFileName, &caCrt);
+
+    // Decoding CA certificate
+    CertificateX509 caCrtStuct = CERTIFICATE_X509_INITIALIZER;
+    PKIError errorCode = DecodeCertificate(caCrt, &caCrtStuct);
+
+    if (errorCode != PKI_SUCCESS)
+    {
+        printf("Unable to decode CA Certificate!\n");
+        printf("Error code: %d\n", errorCode);
+    }
+
+    ByteArray caPublicKey = BYTE_ARRAY_INITIALIZER;
+    // Verifies Certificate or CRL depending on request
+    if (isCrt)
+    {
+        errorCode = CheckCertificate(testedCrtCrl, caCrtStuct.pubKey);
+    }
+    else
+    {
+        caPublicKey.data = caCrtStuct.pubKey.data;
+        caPublicKey.len = caCrtStuct.pubKey.len;
+        ParsePublicKey(&caPublicKey);
+        CertificateList crlStruct = CRL_INITIALIZER;
+        errorCode = DecodeCertificateList(testedCrtCrl, &crlStruct, caPublicKey);
+    }
+
+    if (errorCode == PKI_SUCCESS)
+    {
+        printf("Verification SUCCESS!\n");
+    }
+    else
+    {
+        printf("Verification FAILED!\n");
+        printf("Error code: %d\n", errorCode);
+    }
+
+    // Free the allocated memory
+    OICFree(testedCrtCrl.data);
+    OICFree(caCrt.data);
+
+    return 0;
+}
diff --git a/resource/csdk/security/provisioning/ck_manager/tools/x509_issue.c b/resource/csdk/security/provisioning/ck_manager/tools/x509_issue.c
new file mode 100644 (file)
index 0000000..353971e
--- /dev/null
@@ -0,0 +1,256 @@
+/******************************************************************
+ *
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <getopt.h>
+
+#include "byte_array.h"
+#include "ck_manager.h"
+#include "crl.h"
+
+#define SUCCESS_RES            0
+#define FAIL_RES               1
+
+const char COMMAND_CRT[] = "crt";
+const char COMMAND_CRL[] = "crl";
+
+#define DEFAULT_SN             1
+
+#define DEFAULT_CA_CRT_NAME           "ca_crt.der"
+#define DEFAULT_CA_PUBLIC_KEY_NAME    "ca_public.key"
+#define DEFAULT_USER_PRIVATE_KEY_NAME "user_private.key"
+#define DEFAULT_USER_CRT_NAME         "user_crt.der"
+#define DEFAULT_CRL_NAME              "crl.der"
+
+#define DEFAULT_DER_DATA_SIZE  1024
+#define SET_OF_SEQUENCE_SIZE   4
+#define NUMBER_OF_REVOKED      1
+
+/**
+ * Shows program usage hint.
+ */
+void Usage()
+{
+    printf("Use next command:\n");
+    printf("x509_issue -c <crt/crl> [-n]\n");
+    printf("\t[-c]\t command name crt | crl\n");
+    printf("\t[-n]\t generate new CA key pair\n");
+}
+
+/**
+ * Generates CA Certificate File, writes CA private and public keys to storage
+ *
+ * @param[in]  updateCAkeys use new or old keys
+*/
+int GenerateCACertificateFile(const int updateCAkeys)
+{
+    // Variables definition
+    uint8_t derData[DEFAULT_DER_DATA_SIZE] = {0};
+    uint8_t caPubKey[PUBLIC_KEY_SIZE] = {0};
+    uint8_t caPrivKey[PRIVATE_KEY_SIZE] = {0};
+    uint8_t defaultCaName[] = "Default_CA_Name";
+
+    ByteArray certDer = BYTE_ARRAY_CONSTRUCTOR(derData);
+    ByteArray pubKeyIss = BYTE_ARRAY_CONSTRUCTOR(caPubKey);
+    ByteArray privKeyIss = BYTE_ARRAY_CONSTRUCTOR(caPrivKey);
+    ByteArray rootName = BYTE_ARRAY_CONSTRUCTOR(defaultCaName);
+
+    // Generate
+    if (updateCAkeys)
+    {
+        GenerateCAKeyPair(&privKeyIss, &pubKeyIss);
+        printf("CA key pair was changed!\n");
+        if (GenerateDERCertificateFile(&pubKeyIss, DEFAULT_CA_PUBLIC_KEY_NAME) != PKI_SUCCESS)
+        {
+            printf("Unable to generate CA public key file!\n");
+            exit(0);
+        }
+        else
+        {
+            printf("CA public key file generated: %s\n", DEFAULT_CA_PUBLIC_KEY_NAME);
+        };
+    }
+
+    SetSerialNumber(DEFAULT_SN);
+    SetRootName(rootName);
+    CKMIssueRootCertificate(0, 0, &certDer);
+
+    // Writes ByteArray to file
+    if (GenerateDERCertificateFile(&certDer, DEFAULT_CA_CRT_NAME) != PKI_SUCCESS)
+    {
+        printf("Unable to generate CA Certificate file!\n");
+        exit(0);
+    }
+    else
+    {
+        printf("CA Certificate File generated: %s\n", DEFAULT_CA_CRT_NAME);
+    };
+    return 0;
+}
+
+/**
+ * Generates User Certificate File
+ */
+void GenerateUserCertificateFile()
+{
+    uint8_t subjPubKey[PUBLIC_KEY_SIZE] = {0};
+    uint8_t subjPrivKey[PRIVATE_KEY_SIZE] = {0};
+
+    ByteArray pubKeySubj = BYTE_ARRAY_CONSTRUCTOR(subjPubKey);
+    ByteArray privKeySubj = BYTE_ARRAY_CONSTRUCTOR(subjPrivKey);
+
+    // TODO: Uncomment GenerateKeyPair
+    GenerateKeyPair(&privKeySubj, &pubKeySubj);
+
+    if (GenerateDERCertificateFile(&privKeySubj, DEFAULT_USER_PRIVATE_KEY_NAME) != PKI_SUCCESS)
+    {
+        printf("Unable to generate user private key file!\n");
+        exit(0);
+    }
+    else
+    {
+        printf("User private key file generated: %s\n", DEFAULT_USER_PRIVATE_KEY_NAME);
+    };
+
+    uint8_t derData[DEFAULT_DER_DATA_SIZE] = {0};
+    ByteArray certDer = BYTE_ARRAY_CONSTRUCTOR(derData);
+
+    const uint8_t defaultUserName[]   = "Default_USER_Name";
+
+    CKMIssueDeviceCertificate(defaultUserName, 0, 0, subjPubKey, &certDer);
+
+    if (GenerateDERCertificateFile(&certDer, DEFAULT_USER_CRT_NAME) != PKI_SUCCESS)
+    {
+        printf("Unable to generate User Certificate file!\n");
+        exit(0);
+    }
+    else
+    {
+        printf("User Certificate File generated: %s\n", DEFAULT_USER_CRT_NAME);
+    };
+}
+
+/**
+ * Generates Certificate Revocation List File
+ */
+void GenerateCRLFile()
+{
+    const uint8_t *uint8ThisUpdateTime = (const uint8_t *)"130101000000Z";
+    uint32_t revokedNumbers[NUMBER_OF_REVOKED] = {100};
+    const uint8_t *revocationDates[NUMBER_OF_REVOKED] =
+    {
+        (const uint8_t *)"130101000001Z"
+    };
+
+    ByteArray code =
+    {
+        .len = CRL_MIN_SIZE + NUMBER_OF_REVOKED * (sizeof(CertificateRevocationInfo_t) + SET_OF_SEQUENCE_SIZE),
+        .data = (uint8_t *)calloc(1, CRL_MIN_SIZE + NUMBER_OF_REVOKED * (sizeof(CertificateRevocationInfo_t) + SET_OF_SEQUENCE_SIZE))
+    };
+
+    if (!code.data)
+    {
+        printf("calloc error\n");
+        exit(0);
+    }
+
+    int errorCode = CKMIssueCRL(uint8ThisUpdateTime, NUMBER_OF_REVOKED, revokedNumbers, revocationDates,
+                                &code);
+
+    printf("Gen CRL err code: %d\n", errorCode);
+
+    //CRL ByteArray to file
+    if (GenerateDERCertificateFile(&code, DEFAULT_CRL_NAME) != PKI_SUCCESS)
+    {
+        printf("Unable to generate CRL file!\n");
+        free(code.data);
+        exit(0);
+    }
+    else
+    {
+        printf("CRL File generated: %s\n", DEFAULT_CRL_NAME);
+    };
+
+    free(code.data);
+}
+
+/**
+ * Main function.
+ *
+ * Generates certificate and certificate revocation list
+ *
+ * @param[in]  argc An integer argument count of the command line arguments
+ * @param[in]  argv An argument vector of the command line arguments
+ *
+ * @return[out] an integer 0 upon exit success
+ */
+int main(int argc, char *argv[])
+{
+    int isCrt = 0;
+    int updateCAkeys = 0;
+
+    // Parse command line arguments
+    int opt;
+
+    while ((opt = getopt(argc, argv, "c:n")) != -1)
+    {
+        switch (opt)
+        {
+            case 'c':
+                if (!strcmp(COMMAND_CRT, optarg))
+                {
+                    isCrt = 1;
+                }
+                else if (!strcmp(COMMAND_CRL, optarg))
+                {
+                    isCrt = 0;
+                }
+                else
+                {
+                    printf("Wrong command(-c)!\n");
+                    Usage();
+                    exit(0);
+                }
+                break;
+            case 'n':
+                updateCAkeys = 1;
+                break;
+            default:
+                Usage();
+                exit(0);
+        }
+    }
+
+    // main
+    GenerateCACertificateFile(updateCAkeys);
+
+    if (isCrt)
+    {
+        GenerateUserCertificateFile();
+    }
+    else
+    {
+        GenerateCRLFile();
+    }
+
+    return 0;
+}