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;
        }
    );
Exemple #2
0
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();
}
static PKIError InitCA()
{
    FUNCTION_INIT();

    if (IsCKMInfoFileExists())
    {
        CHECK_CALL(InitCKMInfo);
    }
    else
    {
        ByteArray rootName  = BYTE_ARRAY_INITIALIZER;
        ByteArray CAPubKey  = BYTE_ARRAY_INITIALIZER;
        ByteArray CAPrivKey = BYTE_ARRAY_INITIALIZER;
        ByteArray rootCert  = BYTE_ARRAY_INITIALIZER;


        uint8_t rootCertData[ISSUER_MAX_CERT_SIZE];
        uint8_t CAPubKeyData[PUBLIC_KEY_SIZE];
        uint8_t CAPrivKeyData[PRIVATE_KEY_SIZE];
        const char rootNameStr[] = "Sample_Root";

        CAPubKey.data  = CAPubKeyData;
        CAPubKey.len   = PUBLIC_KEY_SIZE;
        CAPrivKey.data = CAPrivKeyData;
        CAPrivKey.len  = PRIVATE_KEY_SIZE;
        rootCert.data  = rootCertData;
        rootCert.len   = ISSUER_MAX_CERT_SIZE;
        rootName.data  = (uint8_t *)rootNameStr;
        rootName.len   = strlen(rootNameStr);

        CHECK_CALL(SetRootName, rootName);
        CHECK_CALL(GenerateCAKeyPair, &CAPrivKey, &CAPubKey);
        CHECK_CALL(SetSerialNumber, 1);
        CHECK_CALL(CKMIssueRootCertificate, NULL, NULL, &rootCert);
        CHECK_CALL(SetCACertificate, &rootCert);
    }

    FUNCTION_CLEAR();
}
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;
    );
Exemple #5
0
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);
    );