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 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; );
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); );