Commit d1ec67c3 authored by Kevin Kane's avatar Kevin Kane Committed by Greg Zaverucha

Implement /oic/sec/csr resource

Change-Id: I04a98127e2414c2e3c35f00c4d702bb228fb7dec
Signed-off-by: default avatarKevin Kane <kkane@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/17251Reviewed-by: default avatarAlex Kelley <alexke@microsoft.com>
Reviewed-by: default avatarAndrii Shtompel <a.shtompel@samsung.com>
Reviewed-by: default avatarDan Mihai <Daniel.Mihai@microsoft.com>
Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: default avatarGreg Zaverucha <gregz@microsoft.com>
parent 7b6770cb
......@@ -127,6 +127,18 @@ extern "C"
#define CA_OPTION_URI_QUERY 15
#define CA_OPTION_ACCEPT 17
#define CA_OPTION_LOCATION_QUERY 20
/**
* @def UUID_PREFIX
* @brief uuid prefix in certificate subject field
*/
#define UUID_PREFIX "uuid:"
/**
* @def SUBJECT_PREFIX
* @brief prefix for specifying part of a cert's subject for a particular uuid
*/
#define SUBJECT_PREFIX "CN=" UUID_PREFIX
/**
* TODO: Move these COAP defines to CoAP lib once approved.
......
......@@ -42,6 +42,7 @@
#include "mbedtls/pkcs12.h"
#include "mbedtls/ssl_internal.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/oid.h"
#ifdef __WITH_DTLS__
#include "mbedtls/timing.h"
#include "mbedtls/ssl_cookie.h"
......@@ -76,11 +77,6 @@
* @brief Personalization string for the mbedtls RNG
*/
#define PERSONALIZATION_STRING "IOTIVITY_RND"
/**
* @def UUID_PREFIX
* @brief uuid prefix in certificate subject field
*/
#define UUID_PREFIX "uuid:"
/**
* @def USERID_PREFIX
* @brief userid prefix in certificate alternative subject name field
......@@ -1864,41 +1860,75 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
if (MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != selectedCipher &&
MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 != selectedCipher)
{
char uuid[UUID_LENGTH * 2 + 5] = {0};
void * uuidPos = NULL;
void * userIdPos = NULL;
const mbedtls_x509_crt * peerCert = mbedtls_ssl_get_peer_cert(&peer->ssl);
const mbedtls_x509_name * name = NULL;
ret = (NULL == peerCert ? -1 : 0);
SSL_CHECK_FAIL(peer, ret, "Failed to retrieve cert", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_NO_CERT);
uuidPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
if (NULL != uuidPos)
{
memcpy(uuid, (char*) uuidPos + sizeof(UUID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "certificate uuid string: %s" , uuid);
ret = (OCConvertStringToUuid(uuid, peer->sep.identity.id)) ? 0 : -1;
SSL_CHECK_FAIL(peer, ret, "Failed to convert subject", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
}
else
/* Find the CN component of the subject name. */
for (name = &peerCert->subject; NULL != name; name = name->next)
{
OIC_LOG(WARNING, NET_SSL_TAG, "uuid not found");
if (!name->oid.p)
{
continue;
}
if ((name->oid.len < (sizeof(MBEDTLS_OID_AT_CN) - 1) ||
(0 != memcmp(MBEDTLS_OID_AT_CN, name->oid.p, name->oid.len))))
{
continue;
}
}
userIdPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
USERID_PREFIX, sizeof(USERID_PREFIX) - 1);
if (NULL != userIdPos)
if (NULL == name)
{
memcpy(uuid, (char*) userIdPos + sizeof(USERID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
ret = (OCConvertStringToUuid(uuid, peer->sep.userId.id)) ? 0 : -1;
SSL_CHECK_FAIL(peer, ret, "Failed to convert subject alt name", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
OIC_LOG(WARNING, NET_SSL_TAG, "no CN RDN found in subject name");
}
else
{
OIC_LOG(WARNING, NET_SSL_TAG, "Subject alternative name not found");
const size_t uuidBufLen = UUID_STRING_SIZE - 1;
char uuid[UUID_STRING_SIZE] = { 0 };
const unsigned char * uuidPos = NULL;
const unsigned char * userIdPos = NULL;
uuidPos = (const unsigned char*)memmem(name->val.p, name->val.len,
UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
/* If UUID_PREFIX is present, ensure there's enough data for the prefix plus an entire
* UUID, to make sure we don't read past the end of the buffer.
*/
if ((NULL != uuidPos) &&
(name->val.len >= ((uuidPos - name->val.p) + (sizeof(UUID_PREFIX) - 1) + uuidBufLen)))
{
memcpy(uuid, uuidPos + sizeof(UUID_PREFIX) - 1, uuidBufLen);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "certificate uuid string: %s", uuid);
ret = (OCConvertStringToUuid(uuid, peer->sep.identity.id)) ? 0 : -1;
SSL_CHECK_FAIL(peer, ret, "Failed to convert subject", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
}
else
{
OIC_LOG(WARNING, NET_SSL_TAG, "uuid not found");
}
/* If USERID_PREFIX is present, ensure there's enough data for the prefix plus an entire
* UUID, to make sure we don't read past the end of the buffer.
*/
userIdPos = (const unsigned char*)memmem(name->val.p, name->val.len,
USERID_PREFIX, sizeof(USERID_PREFIX) - 1);
if ((NULL != userIdPos) &&
(name->val.len >= ((userIdPos - name->val.p) + (sizeof(USERID_PREFIX) - 1) + uuidBufLen)))
{
memcpy(uuid, userIdPos + sizeof(USERID_PREFIX) - 1, uuidBufLen);
ret = (OCConvertStringToUuid(uuid, peer->sep.userId.id)) ? 0 : -1;
SSL_CHECK_FAIL(peer, ret, "Failed to convert subject alt name", 1,
CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
}
else
{
OIC_LOG(WARNING, NET_SSL_TAG, "Subject alternative name not found");
}
}
}
......
......@@ -123,6 +123,7 @@ if libocsrm_env.get('SECURED') == '1':
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmpincommon.c', OCSRM_SRC + 'pbkdf2.c']
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'crlresource.c', OCSRM_SRC + 'pkix_interface.c']
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmverifycommon.c']
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'certhelpers.c', OCSRM_SRC + 'csrresource.c']
if target_os in ['windows', 'msys_nt']:
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'strptime.c']
......
//******************************************************************
//
// Copyright 2017 Microsoft
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// 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
//
// 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 IOTVT_SRM_CERTHELPERS_H_
#define IOTVT_SRM_CERTHELPERS_H_
#if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
#include "mbedtls/pk.h"
/**
* Internal certificate request function; used by CSR resource handler
*
* @param[in] subject Subject to put into the CSR
* @param[in] keyPair Key pair for which to generate the CSR
* @param[in] encoding Encoding to use; valid values are OIC_ENCODING_PEM and OIC_ENCODING_DER
* @param[out] csr OCByteString containing the CSR in PEM. Caller takes ownership
* of allocated memory and must call OICFree on csr->bytes when finished.
* If encoding is OIC_ENCODING_DER, csr->len is the length of the encoded CSR.
* If encoding is OIC_ENCODING_PEM, csr->len is the length of the PEM string including the
* terminating NULL.
*
* @return 0 on success, <0 on failure
*/
int OCInternalCSRRequest(const char *subject, mbedtls_pk_context *keyPair,
OicEncodingType_t encoding, OCByteString *csr);
/**
* Internal key pair generation function; used by CSR resource handler
*
* @param[in,out] keyPair Key object to generate; caller should already have called mbedtls_pk_init on it.
*
* @return 0 on success, <0 on failure
*/
int OCInternalGenerateKeyPair(mbedtls_pk_context *keyPair);
#endif
#endif
//******************************************************************
//
// Copyright 2017 Microsoft
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// 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
//
// 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 IOTVT_SRM_CSRR_H
#define IOTVT_SRM_CSRR_H
#include "cainterface.h"
#include "securevirtualresourcetypes.h"
#include "octypes.h"
#if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
/**
* Initialize the CSR resource.
*
* @return OC_STACK_OK if successful; error otherwise.
*/
OCStackResult InitCSRResource();
/**
* De-initialize the CSR resource.
*
* @return OC_STACK_OK if successful; error otherwise.
*/
OCStackResult DeInitCSRResource();
/**
* This function converts a CBOR payload into a CSR.
* Caller needs to call 'OICFree' on *csr after use.
*
* @param[in] cborPayload Received CBOR payload to extract the CSR from
* @param[in] size Size of cborPayload
* @param[out] csr Buffer containing the CSR
* @param[out] csrLen Length of csr
* @param[out] encoding Encoding of CSR (OIC_ENCODING_PEM or OIC_ENCODING_DER)
*/
OCStackResult CBORPayloadToCSR(const uint8_t *cborPayload, size_t size,
uint8_t **csr, size_t *csrLen,
OicEncodingType_t *encoding);
#endif
#endif
......@@ -59,6 +59,11 @@ extern const char * OIC_RSRC_CRED_URI;
extern const char * OIC_JSON_CRED_NAME;
extern const char * OIC_JSON_CREDS_NAME;
//csr
extern const char * OIC_RSRC_TYPE_SEC_CSR;
extern const char * OIC_RSRC_CSR_URI;
extern const char * OIC_JSON_CSR_NAME;
//CRL
extern const char * OIC_RSRC_TYPE_SEC_CRL;
extern const char * OIC_RSRC_CRL_URI;
......@@ -162,9 +167,10 @@ extern const char * OIC_JSON_SEC_V_NAME;
extern const char * OIC_JSON_EMPTY_STRING;
// Certificates provided by Cloud
// Certificates provided by Cloud or OBT/CMS
extern const char * TRUST_CA;
extern const char * PRIMARY_CERT;
extern const char * PRIMARY_KEY;
// Certificates provided by manufacturer
extern const char * MF_TRUST_CA;
......
......@@ -74,6 +74,17 @@ OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDevi
OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
OCProvisionResultCB resultCallback);
/**
* API to request the Certificate Signing Request (CSR) resource.
*
* @param[in] selectedDeviceInfo Selected target device.
* @param[in] resultCallback callback provided by API user, callback will be called when
* provisioning request recieves a response from resource server.
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult SRPGetCSRResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
OCGetCSRResultCB resultCallback);
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
/**
......
......@@ -252,6 +252,18 @@ OCStackResult OCGetCredResource(void* ctx, const OCProvisionDev_t *selectedDevic
OCStackResult OCGetACLResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,
OCProvisionResultCB resultCallback);
/**
* This function requests the device provide its Certificate Signing Request (CSR).
*
* @param[in] ctx Application context would be returned in result callback.
* @param[in] selectedDeviceInfo Selected target device.
* @param[in] resultCallback callback provided by API user, callback will be called when provisioning
request recieves a response from resource server.
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCGetCSRResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,
OCGetCSRResultCB resultCallback);
/**
* this function sends Direct-Pairing Configuration to a device.
*
......
......@@ -100,6 +100,15 @@ typedef struct OCPMResult{
OCStackResult res;
}OCProvisionResult_t;
typedef struct OCPMGetCsrResult
{
OicUuid_t deviceId;
OCStackResult res;
uint8_t *csr;
size_t csrLen;
OicEncodingType_t encoding; /* Determines contents of csr; either OIC_ENCODING_DER or OIC_ENCODING_PEM */
} OCPMGetCsrResult_t;
/**
* Owner device type
*/
......@@ -136,6 +145,19 @@ typedef enum OxmAllowTableIdx {
*/
typedef void (*OCProvisionResultCB)(void* ctx, size_t nOfRes, OCProvisionResult_t *arr, bool hasError);
/**
* Callback function definition of CSR retrieve API
*
* @param[OUT] ctx - If user set a context, it will be returned here.
* @param[OUT] nOfRes - total number of results
* @param[OUT] arr - Array of OCPMGetCsrResult_t, containing one entry for each target device. If an entry's res
* member is OC_STACK_OK, then csr and csrLen are valid; otherwise they should not be used.
* This memory is only valid while the callback is executing; callers must make copies if the data
* needs to be kept longer.
* @param[OUT] hasError - If all calls succeded, this will be false. One or more errors, and this will
* be true. Examine the elements of arr to discover which failed.
*/
typedef void (*OCGetCSRResultCB)(void* ctx, size_t nOfRes, OCPMGetCsrResult_t *arr, bool hasError);
/**
* Callback function definition of direct-pairing
......
......@@ -37,6 +37,9 @@
#include "srmutility.h"
#include "pmtypes.h"
#include "oxmverifycommon.h"
#include "mbedtls/config.h"
#include "mbedtls/pem.h"
#include "mbedtls/x509_csr.h"
#ifdef _MSC_VER
#include <io.h>
......@@ -73,6 +76,7 @@ extern "C"
#define _53_RESET_SVR_DB_ 53
#define _60_GET_CRED_ 60
#define _61_GET_ACL_ 61
#define _62_GET_CSR_ 62
#ifdef MULTIPLE_OWNER
#define _70_MOT_CHANGE_MOM_ 70
#define _71_MOT_PROV_PRECONF_PIN_ 71
......@@ -219,7 +223,89 @@ static void getAclCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool ha
g_doneCB = true;
}
static void provisionDPCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
static void getCsrCB(void* ctx, size_t nOfRes, OCPMGetCsrResult_t* arr, bool hasError)
{
if (!hasError)
{
size_t i;
mbedtls_x509_csr csr;
OIC_LOG_V(INFO, TAG, "getCsrCB SUCCEEDED - ctx: %s", (char*)ctx);
for (i = 0; i < nOfRes; i++)
{
char pemBuffer[2048] = { 0 };
char infoBuffer[2048] = { 0 };
size_t olen;
int ret;
if (arr[i].encoding == OIC_ENCODING_DER)
{
ret = mbedtls_pem_write_buffer("-----BEGIN CERTIFICATE REQUEST-----",
"-----END CERTIFICATE REQUEST-----",
arr[i].csr,
arr[i].csrLen,
pemBuffer,
sizeof(pemBuffer),
&olen);
if (ret < 0)
{
OIC_LOG_V(ERROR, TAG, "Couldn't convert CSR into PEM: %d", ret);
pemBuffer[0] = '\0';
}
}
else
{
OICStrcpyPartial(pemBuffer, sizeof(pemBuffer), arr[i].csr, arr[i].csrLen);
}
mbedtls_x509_csr_init(&csr);
ret = mbedtls_x509_csr_parse_der(&csr, arr[i].csr, arr[i].csrLen);
if (ret < 0)
{
OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
infoBuffer[0] = '\0';
}
else
{
ret = mbedtls_x509_csr_info(infoBuffer, sizeof(infoBuffer), "", &csr);
if (ret < 0)
{
OIC_LOG_V(ERROR, TAG, "Couldn't get CSR info buffer: %d", ret);
infoBuffer[0] = '\0';
}
}
mbedtls_x509_csr_free(&csr);
OIC_LOG(INFO, TAG, "getCsrCB success");
// OIC_LOG_V truncates strings, and the entirety of the CSR PEM gets cut off if we use it
printf("getCsrCB: csr[%" PRIuPTR "]:\n%s\n", i, pemBuffer);
printf("getCsrCB: csr info[%" PRIuPTR "]:\n%s\n", i, infoBuffer);
}
}
else
{
OIC_LOG_V(ERROR, TAG, "getCsrCB FAILED - ctx: %s", (char*)ctx);
if (!arr || (0 == nOfRes))
{
printf(" Device List is Empty..\n\n");
}
else
{
size_t lst_cnt;
for (lst_cnt = 0; nOfRes > lst_cnt; ++lst_cnt)
{
printf(" [%" PRIuPTR "] ", lst_cnt + 1);
printUuid((const OicUuid_t*)&arr[lst_cnt].deviceId);
printf(" - result: %d\n", arr[lst_cnt].res);
}
printf("\n");
}
}
g_doneCB = true;
}
static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
{
if(!hasError)
{
......@@ -834,9 +920,19 @@ static int provisionDirectPairing(void)
// for error checking, the return value saved and printed
g_doneCB = false;
printf(" Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
#if defined(_MSC_VER)
#pragma warning(push)
// Suppress C4028: formal parameter 2 different from declaration. getDevInst returns
// OCProvisionDev_t *, which OCProvisionDirectPairing takes as its second parameter.
// The compiler doesn't understand this.
#pragma warning(disable:4028)
#endif
OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
getDevInst((const OCProvisionDev_t *) g_own_list, dev_num),
&pconf, provisionDPCB);
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
if(OC_STACK_OK != rst)
{
OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
......@@ -1124,6 +1220,66 @@ PVACL_ERROR:
return -1;
}
static int getCsr(void)
{
// check |own_list| for retrieving CSR
if(!g_own_list || 1>g_own_cnt)
{
printf(" > Owned Device List, to retrieve CSR, is Empty\n");
printf(" > Please Register Unowned Devices first, with [20] Menu\n");
return 0; // normal case
}
// select device for retrieving CSR
int dev_num = 0;
for( ; ; )
{
printf(" > Enter Device Number, for retrieving CSR: ");
for(int ret=0; 1!=ret; )
{
ret = scanf("%d", &dev_num);
for( ; 0x20<=getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
}
if(0<dev_num && g_own_cnt>=dev_num)
{
break;
}
printf(" Entered Wrong Number. Please Enter Again\n");
}
// call |getDevInst| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
if(!dev)
{
OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
goto GETCSR_ERROR;
}
OCStackResult rst = OCGetCSRResource((void*) g_ctx, dev, getCsrCB);
if(OC_STACK_OK != rst)
{
OIC_LOG_V(ERROR, TAG, "OCGetCSRResource API error: %d", rst);
goto GETCSR_ERROR;
}
if(waitCallbackRet()) // input |g_doneCB| flag implicitly
{
OIC_LOG(ERROR, TAG, "OCGetCSRResource callback error");
goto GETCSR_ERROR;
}
// display the result of get credential
printf(" > Get CSR SUCCEEDED\n");
return 0;
GETCSR_ERROR:
return -1;
}
static int unlinkPairwise(void)
{
// check |own_list| for unlinking pairwise devices
......@@ -2403,7 +2559,8 @@ static void printMenu(void)
printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
printf("** 60. Get the Credential resources of the Selected Device\n");
printf("** 61. Get the ACL resources of the Selected Device\n\n");
printf("** 61. Get the ACL resources of the Selected Device\n");
printf("** 62. Get the CSR of the Selected Device\n\n");
#ifdef MULTIPLE_OWNER
printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
......@@ -2607,6 +2764,12 @@ int main()
OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
}
break;
case _62_GET_CSR_:
if(getCsr())
{
OIC_LOG(ERROR, TAG, "_62_GET_CSR_: error");
}
break;
#ifdef MULTIPLE_OWNER
case _70_MOT_CHANGE_MOM_:
if(changeMultipleOwnershipTrnasferMode())
......
......@@ -391,6 +391,12 @@ OCStackResult OCGetACLResource(void* ctx, const OCProvisionDev_t *selectedDevice
return SRPGetACLResource(ctx, selectedDeviceInfo, resultCallback);
}
OCStackResult OCGetCSRResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,
OCGetCSRResultCB resultCallback)
{
return SRPGetCSRResource(ctx, selectedDeviceInfo, resultCallback);
}
OCStackResult OCReadTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
size_t *chainSize)
......
......@@ -34,6 +34,7 @@
#include "pstatresource.h"
#include "srmresourcestrings.h"
#include "credresource.h"
#include "csrresource.h"
#include "doxmresource.h"
#include "pconfresource.h"
#include "credentialgenerator.h"
......@@ -95,6 +96,15 @@ struct GetSecData {
int numOfResults; /**< Number of results in result array.**/
};
typedef struct GetCsrData GetCsrData_t;
struct GetCsrData {
void *ctx;
const OCProvisionDev_t *deviceInfo; /**< Pointer to PMDevInfo_t.**/