From 610af146b59415455fc55957be5c5edd45f679a9 Mon Sep 17 00:00:00 2001 From: Dmitrii Zhuravlev Date: Wed, 16 Sep 2015 20:38:50 +0300 Subject: [PATCH] CA retrieve PKIX resource from SRM using callbacks Change-Id: I179c485a4b71003115d579b4d9c80ed0bc59f4f6 Signed-off-by: Dmitrii Zhuravlev Reviewed-on: https://gerrit.iotivity.org/gerrit/2601 Reviewed-by: dongik Lee Reviewed-by: Sachin Agrawal Tested-by: Sachin Agrawal --- resource/csdk/connectivity/api/cainterface.h | 19 +++- resource/csdk/connectivity/inc/caadapternetdtls.h | 7 -- resource/csdk/connectivity/inc/pkix/crl.h | 11 +++ .../csdk/connectivity/samples/linux/sample_main.c | 12 +++ .../src/adapter_util/caadapternetdtls.c | 101 +++++++++++++++------ .../csdk/connectivity/src/caconnectivitymanager.c | 35 +++++++ .../csdk/security/include/internal/credresource.h | 4 +- .../csdk/security/include/internal/crlresource.h | 6 ++ resource/csdk/security/src/credresource.c | 12 +-- resource/csdk/security/src/crlresource.c | 16 +++- resource/csdk/security/src/resourcemanager.c | 4 + resource/csdk/security/src/secureresourcemanager.c | 8 ++ 12 files changed, 186 insertions(+), 49 deletions(-) diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h index bc2dc98..80551e2 100644 --- a/resource/csdk/connectivity/api/cainterface.h +++ b/resource/csdk/connectivity/api/cainterface.h @@ -110,7 +110,7 @@ typedef struct // EC private key uint8_t devicePrivateKey[PRIVATE_KEY_SIZE]; -} CADtlsCertCreds_t; +} CADtlsX509Creds_t; /** * @brief Callback function type for getting certificate credentials. @@ -118,7 +118,14 @@ typedef struct * credInfo which is then freed by CA * @return NONE */ -typedef void (*CAGetCertCredentialsHandler)(CADtlsCertCreds_t *credInfo); +typedef int (*CAGetDTLSX509CredentialsHandler)(CADtlsX509Creds_t *credInfo); +/** + * @brief Callback function type for getting CRL. + * @param crlInfo [OUT] Certificate credentials info. Handler has to allocate new memory for + * credInfo which is then freed by CA + * @return NONE + */ +typedef void (*CAGetDTLSCrlHandler)(ByteArray crlInfo); #endif //__WITH_X509__ /** @@ -179,7 +186,13 @@ CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSC * @param GetCertCredentials [IN] GetCert Credetials callback * @return #CA_STATUS_OK */ -CAResult_t CARegisterCertCredentialsHandler(CAGetCertCredentialsHandler GetCertCredentials); +CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetX509Credentials); +/** + * @brief Register callback to get CRL. + * @param GetCrl [IN] GetCrl callback + * @return #CA_STATUS_OK + */ +CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetCrl); #endif //__WITH_X509__ /** diff --git a/resource/csdk/connectivity/inc/caadapternetdtls.h b/resource/csdk/connectivity/inc/caadapternetdtls.h index 1d2c351..d766451 100644 --- a/resource/csdk/connectivity/inc/caadapternetdtls.h +++ b/resource/csdk/connectivity/inc/caadapternetdtls.h @@ -253,13 +253,6 @@ CAResult_t CAAdapterNetDtlsDecrypt(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t dataLen); -#ifdef __WITH_X509__ -/** - * @fn CADeInitX509 - * @brief Deinitializes certificate based credential - */ -void CADeInitX509(); -#endif //__WITH_X509__ #endif /* CA_ADAPTER_NET_DTLS_H_ */ diff --git a/resource/csdk/connectivity/inc/pkix/crl.h b/resource/csdk/connectivity/inc/pkix/crl.h index a3e5a32..9f91e5a 100644 --- a/resource/csdk/connectivity/inc/pkix/crl.h +++ b/resource/csdk/connectivity/inc/pkix/crl.h @@ -52,6 +52,17 @@ typedef struct ByteArray signS; /**< Signature s value.*/ } CertificateList; +/**@def CRL_INITIALIZER + * + * Initializes of existing CRL fields to {NULL, 0}. + */ +#undef CRL_INITIALIZER +#define CRL_INITIALIZER {BYTE_ARRAY_INITIALIZER,\ + BYTE_ARRAY_INITIALIZER,\ + BYTE_ARRAY_INITIALIZER,\ + BYTE_ARRAY_INITIALIZER,\ + BYTE_ARRAY_INITIALIZER} + #ifdef X509_DEBUG /** * Prints Certificate List to console. diff --git a/resource/csdk/connectivity/samples/linux/sample_main.c b/resource/csdk/connectivity/samples/linux/sample_main.c index 0f4fc25..b327c15 100644 --- a/resource/csdk/connectivity/samples/linux/sample_main.c +++ b/resource/csdk/connectivity/samples/linux/sample_main.c @@ -135,6 +135,18 @@ void clearDtlsCredentialInfo() printf("clearDtlsCredentialInfo OUT\n"); } +#ifdef __WITH_X509__ +int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo) +{ + (void) credInfo; + return -1; +} +int * GetCRLResource() +{ + return (int*) NULL; +} +#endif + // Internal API. Invoked by CA stack to retrieve credentials from this module void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo) { diff --git a/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c index bc2dbd0..7705f5f 100644 --- a/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c @@ -28,8 +28,13 @@ #ifdef __WITH_X509__ #include "pki.h" +#include "crl.h" #include "cainterface.h" -#include "credresource.h" + +/* lenght of ASN.1 header in DER format + * for subject field in X.509 certificate */ +#define DER_SUBJECT_HEADER_LEN (9) + #undef VERIFY_SUCCESS #define VERIFY_SUCCESS(op, successCode) { if ((op) != (successCode)) \ {OIC_LOG_V(FATAL, NET_DTLS_TAG, "%s failed!!", #op); goto exit;} } @@ -59,6 +64,19 @@ static ca_mutex g_dtlsContextMutex = NULL; */ static CAGetDTLSCredentialsHandler g_getCredentialsCallback = NULL; +#ifdef __WITH_X509__ +/** + * @var g_getX509CredentialsCallback + * @brief callback to get DTLS certificate credentials + */ +static CAGetDTLSX509CredentialsHandler g_getX509CredentialsCallback = NULL; +/** + * @var g_getCrlCallback + * @brief callback to get CRL for DTLS + */ +static CAGetDTLSCrlHandler g_getCrlCallback = NULL; +#endif //__WITH_X509__ + static CASecureEndpoint_t *GetPeerInfo(const CAEndpoint_t *peer) { uint32_t list_index = 0; @@ -622,6 +640,22 @@ void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback) OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT"); } +#ifdef __WITH_X509__ +void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback) +{ + OIC_LOG(DEBUG, NET_DTLS_TAG, "IN"); + g_getX509CredentialsCallback = credCallback; + OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT"); +} +void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback) +{ + // TODO Does this method needs protection of DtlsContextMutex ? + OIC_LOG(DEBUG, NET_DTLS_TAG, "IN"); + g_getCrlCallback = crlCallback; + OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT"); +} +#endif // __WITH_X509__ + CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher) { OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite"); @@ -782,23 +816,39 @@ CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint, } #ifdef __WITH_X509__ -static CADtlsCertCreds_t g_X509Cred = {{0}, 0, 0, {0}, {0}, {0}}; - -static int g_IsX509Init = 0; +static CADtlsX509Creds_t g_X509Cred = {{0}, 0, 0, {0}, {0}, {0}}; int CAInitX509() { OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CAInitX509"); - g_IsX509Init = (OC_STACK_OK == GetDtlsCertCredentials(&g_X509Cred)); - - OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CAInitX509"); - return !g_IsX509Init; -} + VERIFY_NON_NULL_RET(g_getX509CredentialsCallback, NET_DTLS_TAG, "GetX509Credential callback", -1); + int isX509Init = (0 == g_getX509CredentialsCallback(&g_X509Cred)); + if (isX509Init) + { + uint8_t crlData[CRL_MAX_LEN] = {0}; + ByteArray crlArray = {crlData, CRL_MAX_LEN}; + g_getCrlCallback(crlArray); + if (crlArray.len > 0) + { + uint8_t keyData[PUBLIC_KEY_SIZE] = {0}; + CertificateList crl = CRL_INITIALIZER; + ByteArray rootPubKey = {keyData, PUBLIC_KEY_SIZE}; + memcpy(keyData, g_X509Cred.rootPublicKeyX, PUBLIC_KEY_SIZE / 2); + memcpy(keyData + PUBLIC_KEY_SIZE / 2, g_X509Cred.rootPublicKeyY, PUBLIC_KEY_SIZE / 2); + DecodeCertificateList(crlArray, &crl, rootPubKey); + } + } -void CADeInitX509() -{ - g_IsX509Init = 0; + OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CAInitX509"); + if (isX509Init) + { + return 0; + } + else + { + return 1; + } } @@ -816,10 +866,7 @@ static int CAGetDeviceKey(struct dtls_context_t *ctx, static dtls_ecc_key_t ecdsa_key = {DTLS_ECDH_CURVE_SECP256R1, NULL, NULL, NULL}; int ret = 1; - if (!g_IsX509Init) - { - VERIFY_SUCCESS(CAInitX509(), 0); - } + VERIFY_SUCCESS(CAInitX509(), 0); ecdsa_key.priv_key = g_X509Cred.devicePrivateKey; *result = &ecdsa_key; @@ -837,10 +884,9 @@ CAGetDeviceCertificate(struct dtls_context_t *ctx, { OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetDeviceCertificate"); int ret = 1; - if (!g_IsX509Init) - { - VERIFY_SUCCESS(CAInitX509(), 0); - } + + VERIFY_SUCCESS(CAInitX509(), 0); + *cert = g_X509Cred.certificateChain; *cert_size = g_X509Cred.certificateChainLen; #ifdef X509_DEBUG @@ -863,10 +909,9 @@ static int CAGetRootKey(const unsigned char **ca_pub_x, const unsigned char **ca { OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetRootKey"); int ret = 1; - if (!g_IsX509Init) - { - VERIFY_SUCCESS(CAInitX509(), 0); - } + + VERIFY_SUCCESS(CAInitX509(), 0); + *ca_pub_x = g_X509Cred.rootPublicKeyX; *ca_pub_y = g_X509Cred.rootPublicKeyY; @@ -932,7 +977,7 @@ static int CAVerifyCertificate(struct dtls_context_t *ctx, const session_t *sess CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port); CAResult_t result = CAAddIdToPeerInfoList(peerAddr, port, - crtChain[0].subject.data + crtChain[0].subject.len - sizeof(OicUuid_t), sizeof(OicUuid_t)); + crtChain[0].subject.data + DER_SUBJECT_HEADER_LEN + 2, crtChain[0].subject.data[DER_SUBJECT_HEADER_LEN + 1]); if (CA_STATUS_OK != result ) { OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList"); @@ -948,9 +993,6 @@ exit: #endif - - - CAResult_t CAAdapterNetDtlsInit() { OIC_LOG(DEBUG, NET_DTLS_TAG, "IN"); @@ -1017,8 +1059,7 @@ CAResult_t CAAdapterNetDtlsInit() g_caDtlsContext->callbacks.event = CAHandleSecureEvent; #ifdef __WITH_X509__ - CAInitX509(); - if (g_IsX509Init == 0) + if (0 == CAInitX509()) #endif //__WITH_X509__ g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials; #ifdef __WITH_X509__ diff --git a/resource/csdk/connectivity/src/caconnectivitymanager.c b/resource/csdk/connectivity/src/caconnectivitymanager.c index 7f77d6b..e021b13 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager.c @@ -46,6 +46,13 @@ static bool g_isInitialized = false; extern void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback); #endif +#ifdef __WITH_X509__ +// CAAdapterNetDTLS will register the callback. +// Taking callback all the way through adapters not the right approach, hence calling here. +extern void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback); +extern void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback); +#endif + CAResult_t CAInitialize() { OIC_LOG(DEBUG, TAG, "CAInitialize"); @@ -129,6 +136,34 @@ CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSC } #endif //__WITH_DTLS__ +#ifdef __WITH_X509__ +CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler) +{ + OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler"); + + if(!g_isInitialized) + { + return CA_STATUS_NOT_INITIALIZED; + } + + CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler); + return CA_STATUS_OK; +} + +CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler) +{ + OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler"); + + if(!g_isInitialized) + { + return CA_STATUS_NOT_INITIALIZED; + } + + CADTLSSetCrlCallback(GetDTLSCrlHandler); + return CA_STATUS_OK; +} +#endif //__WITH_X509__ + CAResult_t CACreateEndpoint(CATransportFlags_t flags, CATransportAdapter_t adapter, const char *addr, diff --git a/resource/csdk/security/include/internal/credresource.h b/resource/csdk/security/include/internal/credresource.h index 7ee74a1..9af4e20 100644 --- a/resource/csdk/security/include/internal/credresource.h +++ b/resource/csdk/security/include/internal/credresource.h @@ -152,9 +152,9 @@ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t cre * @param credInfo * binary structure containing certificate credentials * - * @retval OC_STACK_OK on scuccess + * @retval 0 on scuccess */ -OCStackResult GetDtlsCertCredentials(CADtlsCertCreds_t *credInfo); +int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo); #endif /*__WITH_X509__*/ /** diff --git a/resource/csdk/security/include/internal/crlresource.h b/resource/csdk/security/include/internal/crlresource.h index 2e69523..75178d8 100644 --- a/resource/csdk/security/include/internal/crlresource.h +++ b/resource/csdk/security/include/internal/crlresource.h @@ -43,6 +43,12 @@ OCStackResult UpdateCRLResource(const OicSecCrl_t *crl); * @note Caller responsible for resulting string memory (use OICFree to remove it) */ char* GetBase64CRL(); +/** + * This function get encoded with DER CRL from SRM + * + * @returns encoded CRL with DER format. array len is 0 if error occured (e.g. CRL did not set) + */ +void GetDerCrl(ByteArray crlArray); /** * This function get CRL from SRM diff --git a/resource/csdk/security/src/credresource.c b/resource/csdk/security/src/credresource.c index 748126a..d0c5e60 100644 --- a/resource/csdk/security/src/credresource.c +++ b/resource/csdk/security/src/credresource.c @@ -1028,7 +1028,7 @@ exit: return ret; } -static OCStackResult GetCAPublicKeyData(CADtlsCertCreds_t *credInfo){ +static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo){ OCStackResult ret = OC_STACK_ERROR; uint8_t *ccPtr = credInfo->certificateChain; for(uint32_t i =0; i < credInfo->chainLen - 1; ++i) @@ -1054,7 +1054,7 @@ static OCStackResult GetCAPublicKeyData(CADtlsCertCreds_t *credInfo){ return ret; } -static OCStackResult GetCertCredPublicData(CADtlsCertCreds_t *credInfo, OicSecCred_t *cred) +static OCStackResult GetCertCredPublicData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred) { OCStackResult ret = OC_STACK_ERROR; VERIFY_NON_NULL(TAG, credInfo, ERROR); @@ -1090,7 +1090,7 @@ exit: return ret; } -static OCStackResult GetCertCredPrivateData(CADtlsCertCreds_t *credInfo, OicSecCred_t *cred) +static OCStackResult GetCertCredPrivateData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred) { OCStackResult ret = OC_STACK_ERROR; VERIFY_NON_NULL(TAG, credInfo, ERROR); @@ -1114,9 +1114,9 @@ exit: return ret; } -OCStackResult GetDtlsCertCredentials(CADtlsCertCreds_t *credInfo) +int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo) { - OCStackResult ret = OC_STACK_ERROR; + int ret = 1; VERIFY_NON_NULL(TAG, credInfo, ERROR); if (NULL == gCred) { @@ -1130,7 +1130,7 @@ OCStackResult GetDtlsCertCredentials(CADtlsCertCreds_t *credInfo) VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPrivateData(credInfo, cred), ERROR); VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPublicData(credInfo, cred), ERROR); - ret = OC_STACK_OK; + ret = 0; exit: return ret; diff --git a/resource/csdk/security/src/crlresource.c b/resource/csdk/security/src/crlresource.c index 36d005f..7a1e5d8 100644 --- a/resource/csdk/security/src/crlresource.c +++ b/resource/csdk/security/src/crlresource.c @@ -34,7 +34,6 @@ #ifdef __WITH_X509__ #include "crlresource.h" #include "crl.h" -#include "ckm_info.h" #endif /* __WITH_X509__ */ #define TAG PCF("SRM-CRL") @@ -507,3 +506,18 @@ exit: cJSON_Delete(jsonRoot); return ret; } + +void GetDerCrl(ByteArray crlArray) +{ + OicSecCrl_t * crlRes = GetCRLResource(); + if (crlRes && crlRes->CrlData.len <= crlArray.len) + { + memcpy(crlArray.data, crlRes->CrlData.data, crlRes->CrlData.len); + crlArray.len = crlRes->CrlData.len; + } + else + { + crlArray.len = 0; + } + DeleteCrlBinData(crlRes); +} diff --git a/resource/csdk/security/src/resourcemanager.c b/resource/csdk/security/src/resourcemanager.c index 0be77a3..afc991e 100644 --- a/resource/csdk/security/src/resourcemanager.c +++ b/resource/csdk/security/src/resourcemanager.c @@ -32,6 +32,10 @@ #include "utlist.h" #include +#ifdef __WITH_X509__ +#include "crlresource.h" +#endif // __WITH_X509__ + #define TAG PCF("SRM-RM") /** diff --git a/resource/csdk/security/src/secureresourcemanager.c b/resource/csdk/security/src/secureresourcemanager.c index ab56071..e90073e 100644 --- a/resource/csdk/security/src/secureresourcemanager.c +++ b/resource/csdk/security/src/secureresourcemanager.c @@ -28,6 +28,10 @@ #include "oic_string.h" #include +#ifdef __WITH_X509__ +#include "crlresource.h" +#endif // __WITH_X509__ + #define TAG PCF("SRM") //Request Callback handler @@ -253,6 +257,10 @@ OCStackResult SRMInitSecureResources() #if defined(__WITH_DTLS__) CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials); #endif // (__WITH_DTLS__) +#if defined(__WITH_X509__) + CARegisterDTLSX509CredentialsHandler(GetDtlsX509Credentials); + CARegisterDTLSCrlHandler(GetDerCrl); +#endif // (__WITH_X509__) return OC_STACK_OK; } -- 2.7.4