Commit 923688ce authored by Steven Saunders's avatar Steven Saunders Committed by Nathan Heldt-Sheller

add optional cert extensions

Change-Id: I11ee97610c01f464dba896e600c71831629650bc
Signed-off-by: default avatarSteven Saunders <s.saunders-contractor@cablelabs.com>
parent fa07c431
......@@ -30,6 +30,7 @@
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/oid.h>
#include <mbedtls/pem.h>
#include <mbedtls/asn1write.h>
#include "oic_platform.h"
#include "oic_malloc.h"
......@@ -55,6 +56,7 @@ static void FreeTestCert(mbedtls_x509_crt *cert);
static void removeCertChaining(mbedtls_x509_crt* rootCert, mbedtls_x509_crt* intCert, mbedtls_x509_crt* eeCert);
static CertProfileResult SetNotBefore(ValidityTime notBefore, bool invalid);
static CertProfileResult SetNotAfter(ValidityTime notAfter, bool invalid);
static int OCWriteBasicConstraints( mbedtls_x509write_cert *ctx, int is_ca, int max_pathlen, int critical);
class CACertProfileTests : public testing::Test {
protected:
......@@ -102,6 +104,63 @@ static const OCByteString s_ekuOcfIdentityOid = { s_ekuOcfIdentityOidBytes, size
static const OCByteString s_ekuAnyOid = { s_ekuAnyOidBytes, sizeof(s_ekuAnyOidBytes) };
static const char s_ComplianceExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x00"; // 1.3.6.1.4.1.51414.1.0
static const uint8_t s_ComplianceExtBytes[] = {
0x30, 0x81, 0x8C, // compliance extension sequence
0x30, 0x09, // version sequence (9 bytes)
0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, // [2, 0, 0]
0x30, 0x64, // security profile sequence (100 bytes)
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.1.0' (baseline)
0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x31, 0x2E, 0x30,
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.2.0' (black)
0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x32, 0x2E, 0x30,
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.3.0' (blue)
0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x33, 0x2E, 0x30,
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.4.0' (purple)
0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x34, 0x2E, 0x30,
0x0C, 0x0F, // urf8_string 15 bytes long (device name)
0x49, 0x6F, 0x54, 0x69, 0x76, 0x69, 0x74, 0x79, 0x20, 0x53, // 'IoTivity Server'
0x65, 0x72, 0x76, 0x65, 0x72,
0x0C, 0x08, // urf8_string 8 bytes long (device manufacturer)
0x49, 0x6F, 0x54, 0x69, 0x76, 0x69, 0x74, 0x79 // 'IoTivity'
};
static const char s_cplSecurityClaimsExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x01"; // 1.3.6.1.4.1.51414.1.1
static const uint8_t s_cplSecurityClaimsExtBytes[] = {
0x30, 0x1A, // sequence of length 26
0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x91, 0x56, 0x01, 0x01, 0x00, // OID 1.3.6.1.4.1.51414.1.1.0 (claim secure boot)
0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x91, 0x56, 0x01, 0x01, 0x01 // OID 1.3.6.1.4.1.51414.1.1.1 (claim hw backed credential)
};
static const char s_cplAttributesExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x02"; // 1.3.6.1.4.1.51414.1.2
static const uint8_t s_cplAttributesExtBytes[] = {
0x30, 0x20, // sequence of length 32
0x0C, 0x0E, // utf8_string, 14 bytes long
0X31, 0X2E, 0X33, 0X2E, 0X36, 0X2E, 0X31, 0X2E, 0X34, 0X2E, 0X31, 0X2E, 0X37, 0X31, // '1.3.6.1.4.1.71'
0x0C, 0x09, // utf8_string, 9 bytes long
0X44, 0X69, 0X73, 0X63, 0X6F, 0X76, 0X65, 0X72, 0X79, // 'Discovery'
0x0C, 0x03, // utf8_string, 3 bytes long
0X31, 0X2E, 0X30 // '1.0'
};
// The key pairs below are OCF compliant ellliptic curve key pairs
// (RFC 5480 secp256r1 keys) generated by the IoTivity`certgenerator` utility.
// They are used as the public and signing keys for certificates
......@@ -744,6 +803,7 @@ static CertProfileResult GenerateTestCert(CertType certType, CertProfileViolatio
int isCa = 0;
int maxPathLen = 0;
int critical = 0;
unsigned int usage = 0;
bool makeDateInvalid = false;
......@@ -893,18 +953,21 @@ static CertProfileResult GenerateTestCert(CertType certType, CertProfileViolatio
case CERT_CA_ROOT:
isCa = (violations & CP_INVALID_BASIC_CONSTRAINTS_CA) ? 0 : 1;
maxPathLen = (violations & CP_INVALID_BASIC_CONSTRAINTS_PATH_LEN) ? 2 :-1;
critical = 1;
break;
case CERT_CA_INT:
isCa = (violations & CP_INVALID_BASIC_CONSTRAINTS_CA) ? 0 : 1;
maxPathLen = (violations & CP_INVALID_BASIC_CONSTRAINTS_PATH_LEN) ? -1 : 0;
critical = 1;
break;
case CERT_EE:
isCa = (violations & CP_INVALID_BASIC_CONSTRAINTS_CA) ? 1 : 0;
maxPathLen = (violations & CP_INVALID_BASIC_CONSTRAINTS_PATH_LEN) ? 10 : -1;
critical = 0;
break;
};
mbedRet = mbedtls_x509write_crt_set_basic_constraints(&outCertCtx, isCa, maxPathLen);
mbedRet = OCWriteBasicConstraints(&outCertCtx, isCa, maxPathLen, critical );
CP_LOG_MBED_ERROR(TAG, mbedRet, mbedErrBuf, sizeof(mbedErrBuf), ERROR);
cpResult = (0 == mbedRet) ? CP_STATUS_OK : CP_STATUS_FAILED;
VERIFY_SUCCESS_OR_EXIT(TAG, 0 == mbedRet, "Problem writing basic constraints", ERROR);
......@@ -996,6 +1059,51 @@ static CertProfileResult GenerateTestCert(CertType certType, CertProfileViolatio
}
}
// Optional extensions
if (CERT_EE == certType)
{
// FILE *fp = fopen("./cpl.der", "wb");
// fwrite(s_cplAttributesExtBytes, sizeof(s_cplAttributesExtBytes), 1, fp );
// fclose(fp);
mbedRet = mbedtls_x509write_crt_set_extension(
&outCertCtx,
s_cplAttributesExtOid,
MBEDTLS_OID_SIZE(s_cplAttributesExtOid), 0,
(const unsigned char*)s_cplAttributesExtBytes, sizeof(s_cplAttributesExtBytes));
CP_LOG_MBED_ERROR(TAG, mbedRet, mbedErrBuf, sizeof(mbedErrBuf), ERROR);
cpResult = (0 == mbedRet) ? CP_STATUS_OK : CP_STATUS_FAILED;
VERIFY_SUCCESS_OR_EXIT(TAG, (0 == mbedRet), "Problem writing certified product list extension", ERROR);
// fp = fopen("./claims.der", "wb");
// fwrite(s_cplSecurityClaimsExtBytes, sizeof(s_cplSecurityClaimsExtBytes), 1, fp );
// fclose(fp);
mbedRet = mbedtls_x509write_crt_set_extension(
&outCertCtx,
s_cplSecurityClaimsExtOid,
MBEDTLS_OID_SIZE(s_cplSecurityClaimsExtOid), 0,
(const unsigned char*)s_cplSecurityClaimsExtBytes, sizeof(s_cplSecurityClaimsExtBytes));
CP_LOG_MBED_ERROR(TAG, mbedRet, mbedErrBuf, sizeof(mbedErrBuf), ERROR);
cpResult = (0 == mbedRet) ? CP_STATUS_OK : CP_STATUS_FAILED;
VERIFY_SUCCESS_OR_EXIT(TAG, (0 == mbedRet), "Problem writing certified product list extension", ERROR);
// fp = fopen("./compliance.der", "wb");
// fwrite(s_ComplianceExtBytes, sizeof(s_ComplianceExtBytes), 1, fp );
// fclose(fp);
mbedRet = mbedtls_x509write_crt_set_extension(
&outCertCtx,
s_ComplianceExtOid,
MBEDTLS_OID_SIZE(s_ComplianceExtOid), 0,
(const unsigned char*)s_ComplianceExtBytes, sizeof(s_ComplianceExtBytes));
CP_LOG_MBED_ERROR(TAG, mbedRet, mbedErrBuf, sizeof(mbedErrBuf), ERROR);
cpResult = (0 == mbedRet) ? CP_STATUS_OK : CP_STATUS_FAILED;
VERIFY_SUCCESS_OR_EXIT(TAG, (0 == mbedRet), "Problem writing certified product list extension", ERROR);
}
// Create the cert
mbedRet = mbedtls_x509write_crt_pem(&outCertCtx, (uint8_t *)buf, sizeof(buf), mbedtls_ctr_drbg_random, &ctr_drbg);
......@@ -1147,6 +1255,42 @@ static void InitTestCert(mbedtls_x509_crt *cert)
}
// write basic constraints to a cert
// Same as mbedtls_x509write_crt_set_basic_constraints, with the added ability to set `critical` flag
// returns mbedtls error
static int OCWriteBasicConstraints( mbedtls_x509write_cert *ctx, int is_ca, int max_pathlen, int critical)
{
int ret;
unsigned char buf[9];
unsigned char *c = buf + sizeof(buf);
size_t len = 0;
memset( buf, 0, sizeof(buf) );
if( is_ca && max_pathlen > 127 )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
if( is_ca )
{
if( max_pathlen >= 0 )
{
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) );
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) );
return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
critical, buf + sizeof(buf) - len, len );
}
static void FreeTestCert(mbedtls_x509_crt *cert)
{
mbedtls_x509_crt_free(cert);
......
{
"cred": {
"creds": [
{
"credid": 1,
"subjectuuid": "12121212-1212-1212-1212-121212121212",
"credtype": 8,
"publicdata": {
"encoding": "oic.sec.encoding.der",
"data": "$PUBLIC_EE_KEY"
},
"credusage": "oic.sec.cred.mfgcert",
"privatedata": {
"encoding": "oic.sec.encoding.raw",
"data": "$PRIVATE_EE_KEY"
}
},
{
"credid": 2,
"subjectuuid": "12121212-1212-1212-1212-121212121212",
"credtype": 8,
"publicdata": {
"encoding": "oic.sec.encoding.der",
"data": "$PUBLIC_SUBCA_KEY"
},
"credusage": "oic.sec.cred.mfgcert"
},
{
"credid": 3,
"subjectuuid": "*",
"credtype": 8,
"publicdata": {
"encoding": "oic.sec.encoding.der",
"data": "$PUBLIC_PEER_ROOT_KEY",
"revstat": false
},
"credusage": "oic.sec.cred.mfgtrustca"
}
],
"rowneruuid": "12121212-1212-1212-1212-121212121212",
"rt": ["oic.r.cred"],
"if": ["oic.if.baseline"]
},
"acl": {
"aclist2": [
{
"aceid": 1,
"subject": { "conntype": "anon-clear" },
"resources": [
{ "href": "/oic/res" },
{ "href": "/oic/d" },
{ "href": "/oic/p"}
],
"permission": 2
},
{
"aceid": 2,
"subject": { "conntype": "auth-crypt" },
"resources": [
{ "href": "/oic/res" },
{ "href": "/oic/d" },
{ "href": "/oic/p"}
],
"permission": 2
},
{
"aceid": 3,
"subject": { "conntype": "anon-clear" },
"resources": [
{ "href": "/oic/sec/doxm" }
],
"permission": 14
},
{
"aceid": 4,
"subject": { "conntype": "auth-crypt" },
"resources": [
{ "href": "/oic/sec/doxm" },
{ "href": "/oic/sec/roles" }
],
"permission": 14
}
],
"rowneruuid": "12121212-1212-1212-1212-121212121212",
"rt": ["oic.r.acl"],
"if": ["oic.if.baseline"]
},
"pstat": {
"dos": {
"s": 1,
"p": false
},
"isop": false,
"cm": 2,
"tm": 0,
"om": 4,
"sm": 4,
"rowneruuid": "12121212-1212-1212-1212-121212121212",
"rt": ["oic.r.pstat"],
"if": ["oic.if.baseline"]
},
"doxm": {
"oxms": [2],
"oxmsel": 2,
"sct": 9,
"owned": false,
"deviceuuid": "12121212-1212-1212-1212-121212121212",
"devowneruuid": "12121212-1212-1212-1212-121212121212",
"rowneruuid": "12121212-1212-1212-1212-121212121212",
"x.org.iotivity.dpc": true,
"rt": ["oic.r.doxm"],
"if": ["oic.if.baseline"]
}
}
{
"sp": {
"supportedprofiles": [ "1.3.6.1.4.1.51414.0.2.0", "1.3.6.1.4.1.51414.0.3.0", "1.3.6.1.4.1.51414.0.4.0", "1.3.6.1.4.1.51414.0.1.0" ],
"currentprofile": "1.3.6.1.4.1.51414.0.1.0",
"rowneruuid": "00000000-0000-0000-0000-000000000000",
"rt": ["oic.r.sp"],
"if": ["oic.if.baseline"]
},
"cred": {
"creds": [
{
"credid": 1,
"subjectuuid": "89898989-8989-8989-8989-898989898989",
"credtype": 8,
"publicdata": {
"encoding": "oic.sec.encoding.der",
"data": "$PUBLIC_EE_KEY"
},
"credusage": "oic.sec.cred.mfgcert",
"privatedata": {
"encoding": "oic.sec.encoding.raw",
"data": "$PRIVATE_EE_KEY"
}
},
{
"credid": 2,
"subjectuuid": "89898989-8989-8989-8989-898989898989",
"credtype": 8,
"publicdata": {
"encoding": "oic.sec.encoding.der",
"data": "$PUBLIC_SUBCA_KEY"
},
"credusage": "oic.sec.cred.mfgcert"
},
{
"credid": 3,
"subjectuuid": "*",
"credtype": 8,
"publicdata": {
"encoding": "oic.sec.encoding.der",
"data": "$PUBLIC_PEER_ROOT_KEY",
"revstat": false
},
"credusage": "oic.sec.cred.mfgtrustca"
}
],
"rowneruuid": "00000000-0000-0000-0000-000000000000",
"rt": ["oic.r.cred"],
"if": ["oic.if.baseline"]
},
"acl": {
"aclist2": [
{
"aceid": 1,
"subject": { "conntype": "anon-clear" },
"resources": [
{ "href": "/oic/res" },
{ "href": "/oic/d" },
{ "href": "/oic/p"}
],
"permission": 2
},
{
"aceid": 2,
"subject": { "conntype": "auth-crypt" },
"resources": [
{ "href": "/oic/res" },
{ "href": "/oic/d" },
{ "href": "/oic/p"}
],
"permission": 2
},
{
"aceid": 3,
"subject": { "conntype": "anon-clear" },
"resources": [
{ "href": "/oic/sec/doxm" }
],
"permission": 14
},
{
"aceid": 4,
"subject": { "conntype": "auth-crypt" },
"resources": [
{ "href": "/oic/sec/doxm" },
{ "href": "/oic/sec/roles" }
],
"permission": 14
},
{
"aceid": 5,
"subject": { "uuid": "11111111-1111-1111-1111-111111111111" },
"resources": [
{ "href": "/oic/sec/acl2" },
{ "href": "/oic/sec/cred" },
{ "href": "/oic/sec/doxm" },
{ "href": "/oic/sec/pstat" },
{ "href": "/oic/sec/csr" },
{ "href": "/oic/sec/sp" }
],
"permission": 15
}
],
"rowneruuid": "00000000-0000-0000-0000-000000000000",
"rt": ["oic.r.acl"],
"if": ["oic.if.baseline"]
},
"pstat": {
"dos": {
"s": 1,
"p": false
},
"isop": false,
"cm": 2,
"tm": 0,
"om": 4,
"sm": 4,
"rowneruuid": "00000000-0000-0000-0000-000000000000",
"rt": ["oic.r.pstat"],
"if": ["oic.if.baseline"]
},
"doxm": {
"oxms": [2],
"oxmsel": 2,
"sct": 9,
"owned": false,
"deviceuuid": "89898989-8989-8989-8989-898989898989",
"devowneruuid": "00000000-0000-0000-0000-000000000000",
"rowneruuid": "00000000-0000-0000-0000-000000000000",
"rt": ["oic.r.doxm"],
"if": ["oic.if.baseline"]
}
}
#! /bin/bash
if [ $# -ne 1 ]
then
echo "makecerts output_dir"
exit
fi
#----------------------------------------------------------------------------
function GEN_SEED_CERTS () {
#----------------------------------------------------------------------------
../certgenerator <<EOD
1
root
1
subca
1
$CLIENT
1
$SERVER
2
root
C=US, O=Open Connectivity Foundation, CN=Root CA
3
subca
root
C=US, O=Open Connectivity Foundation, CN=Sub CA
4
$CLIENT
subca
12121212-1212-1212-1212-121212121212
4
$SERVER
subca
89898989-8989-8989-8989-898989898989
0
EOD
}
#----------------------------------------------------------------------------
function PEM_2_DER () {
#----------------------------------------------------------------------------
IN_PEM=$1
OUT_DER=$(basename $IN_PEM .pem).der
OUT_HEX=$OUT_DER.hex
openssl x509 -in $IN_PEM -out $OUT_DER -outform der
xxd -ps $OUT_DER | tr -d \\n > $OUT_HEX
}
#----------------------------------------------------------------------------
function ECKEY_PEM_2_DER () {
#----------------------------------------------------------------------------
IN_PEM=$1
OUT=`basename $1`.der
OUT_DER=$(basename $IN_PEM .pem).der
OUT_HEX=$OUT_DER.hex
openssl ec -inform PEM -in $IN_PEM -outform DER -out $OUT_DER
cat $OUT_DER | xxd -ps | tr -d \\n >> $OUT_HEX
}
#----------------------------------------------------------------------------
function BUILD_CERT_PKG () {
#----------------------------------------------------------------------------
CERT_NAME=$1
mkdir -p $CERT_NAME
cp "originals/${CERT_NAME}.crt" "${CERT_NAME}/${CERT_NAME}_cert.pem"
cp "originals/${CERT_NAME}.prv" "${CERT_NAME}/${CERT_NAME}_key.pem"
cd ./$CERT_NAME
PEM_2_DER "${CERT_NAME}_cert.pem"
ECKEY_PEM_2_DER "${CERT_NAME}_key.pem"
mkdir -p chain
cp ../originals/root.crt chain/0-root-cert.pem
cp ../originals/subca.crt chain/1-subca-cert.pem
cd chain
PEM_2_DER 0-root-cert.pem
PEM_2_DER 1-subca-cert.pem
cd ../..
}
#----------------------------------------------------------------------------
function BUILD_CONFIG () {
#----------------------------------------------------------------------------
MY_CERT_NAME=$1
PEER_CERT_NAME=$2
CONFIG_TEMPLATE=${3}.json
J2C=../../../tool/json2cbor
J2C_OUT=${3}.dat
sed -e "s/\$PUBLIC_EE_KEY/$(sed 's:/:\\/:g' ./${MY_CERT_NAME}/${MY_CERT_NAME}_cert.der.hex)/" ../config-templates/${CONFIG_TEMPLATE} > ${CONFIG_TEMPLATE}
sed -i "s/\$PRIVATE_EE_KEY/$(sed 's:/:\\/:g' ./${MY_CERT_NAME}/${MY_CERT_NAME}_key.der.hex)/" ${CONFIG_TEMPLATE}
sed -i "s/\$PUBLIC_SUBCA_KEY/$(sed 's:/:\\/:g' ./${MY_CERT_NAME}/chain/1-subca-cert.der.hex)/" ${CONFIG_TEMPLATE}
sed -i "s/\$PUBLIC_PEER_ROOT_KEY/$(sed 's:/:\\/:g' ./${PEER_CERT_NAME}/chain/0-root-cert.der.hex)/" ${CONFIG_TEMPLATE}
$J2C $CONFIG_TEMPLATE $J2C_OUT
}
#--------------------------------------------------------------------------------------
OUT_DIR=$1
CLIENT=client
SERVER=server
mkdir -p $OUT_DIR
cd $OUT_DIR
GEN_SEED_CERTS
mkdir -p originals
mv *.pub *.prv *.crt originals/.
BUILD_CERT_PKG $CLIENT
BUILD_CERT_PKG $SERVER
BUILD_CONFIG $CLIENT $SERVER oic_svr_db_client
BUILD_CONFIG $SERVER $CLIENT oic_svr_db_server_mfg
......@@ -51,6 +51,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/pem.h"
#include "mbedtls/base64.h"
#include "mbedtls/asn1write.h"
#ifndef NDEBUG
#include "mbedtls/debug.h"
......@@ -91,6 +92,63 @@ static const unsigned char s_ekuRole[] = { 0x30, 0x0C, 0x06, 0x0A, 0x2B, 0x06, 0
/* ASN.1 DER encoding of the EKU for both identity and roles (for use by CAs) */
static const unsigned char s_ekuCA[] = { 0x30, 0x18, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x06, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDE, 0x7C, 0x01, 0x07 };
static const char s_ComplianceExtOid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x04\x01\x83\x91\x56\x01\x00"; // 1.3.6.1.4.1.51414.1.0
static const uint8_t s_ComplianceExtBytes[] = {
0x30, 0x81, 0x8C, // compliance extension sequence
0x30, 0x09, // version sequence (9 bytes)
0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, // [2, 0, 0]
0x30, 0x64, // security profile sequence (100 bytes)
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.1.0' (baseline)
0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x31, 0x2E, 0x30,
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.2.0' (black)
0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E,
0x31, 0x2E, 0x35, 0x31, 0x34, 0x31, 0x34, 0x2E, 0x30, 0x2E, 0x32, 0x2E, 0x30,
0x0C, 0x17, // utf8_string, 23 bytes long, '1.3.6.1.4.1.51414.0.3.0' (blue)