AUTOSAR图解==>AUTOSAR_AP_TR_DDSSecurityIntegration
AUTOSAR Adaptive Platform DDS Security集成详解
目录
- 1. 概述
- 1.1 文档目的
- 1.2 DDS Security简介
- 1.3 技术范围
- 2. DDS Security配置工作流程
- 2.1 工作流程概览
- 2.2 配置阶段详解
- 2.3 部署阶段详解
- 2.4 运行时阶段详解
- 3. AUTOSAR元模型到DDS Security的映射
- 3.1 元模型类图结构
- 3.2 核心配置类详解
- 3.3 类之间的关系
- 4. DDS Security架构
- 4.1 系统架构概览
- 4.2 组件层次结构
- 4.3 接口和交互
- 5. DDS Security Governance Document
- 5.1 Governance Document结构
- 5.2 域规则配置
- 5.3 主题访问规则
- 5.4 AUTOSAR元模型映射
- 6. DDS Security Permissions Document
- 6.1 Permissions Document结构
- 6.2 Grant元素详解
- 6.3 发布和订阅权限
- 6.4 AUTOSAR元模型映射
- 7. 运行时配置和通信序列
- 7.1 初始化序列
- 7.2 发现序列
- 7.3 通信序列
- 8. 代码实现示例
- 8.1 配置数据结构
- 8.2 运行时API调用
- 8.3 安全通信示例
- 9. 总结
- 9.1 关键特性
- 9.2 应用场景
- 9.3 最佳实践
1. 概述
1.1 文档目的
本文档提供了AUTOSAR Adaptive Platform与DDS Security集成的详细技术说明。DDS Security是Data Distribution Service (DDS)的补充标准,提供传输无关的安全措施,包括身份认证、保密性、不可否认性、完整性、访问控制和日志记录。
本技术报告的主要目的是:
- 映射关系说明:阐明AUTOSAR Service Interface和Instance Deployment模型如何映射到DDS QoS策略和DDS Security证书、治理和权限文档
- 配置指导:提供DDS Security制品的生成和部署流程
- 集成方案:展示如何在不修改应用程序逻辑的前提下实现安全通信
1.2 DDS Security简介
DDS Security (OMG DDS Security v1.1) 是DDS标准的安全扩展,提供以下安全机制:
- 身份认证 (Authentication):验证Domain Participant的身份
- 访问控制 (Access Control):控制对域、分区和主题的访问权限
- 加密和完整性保护 (Cryptography):保护数据传输的机密性和完整性
- 不可否认性 (Non-repudiation):通过数字签名确保消息来源的可追溯性
- 日志记录 (Logging):记录安全相关事件
DDS Security通过插件架构实现,主要包括三个插件:
- Authentication Plugin:处理身份认证
- Access Control Plugin:处理访问控制
- Cryptographic Plugin:处理加密和签名
1.3 技术范围
本文档涵盖以下技术范围:
支持的安全特性:
- Per-instance, per-event访问控制:包括保密性和身份认证配置,适用于入站和出站流量
- Per-instance, per-field notifier访问控制:包括保密性和身份认证配置,适用于入站和出站流量
- Per-instance methods访问控制:包括保密性和身份认证配置,适用于入站和出站流量
- Per-instance field methods (Get/Set)访问控制:包括保密性和身份认证配置,适用于入站和出站流量
不支持的特性:
由于DDS Network Binding的特定设计,目前不支持针对独立方法和字段方法(Get/Set)的细粒度安全控制。这是因为属于单个Service Interface Instance的所有方法都复用有限数量的DDS Topics。
配置制品:
文档详细说明了以下DDS Security制品的生成和配置:
- Identity Certificates:身份证书
- Governance Documents:治理文档
- Permissions Documents:权限文档
- QoS Profiles:服务质量配置文件
2. DDS Security配置工作流程
2.1 工作流程概览
DDS Security的配置工作流程展示了从设计时建模到运行时安全通信的完整流程。整个流程分为四个主要阶段:
阶段一:建模DDS特定部署
在这个阶段,系统设计者需要:
- 定义Service Interfaces:按照AUTOSAR Manifest规范定义服务接口
- 配置Service Instances:为服务实例配置DDS特定的部署信息
- 关联到Machine:通过
DdsServiceInstanceToMachineMapping
将服务实例映射到具体的机器和通信连接器
阶段二:配置DDS Security元素
这个阶段包含两个核心配置活动:
1. 定义DdsSecureComProps
DdsSecureComProps
是DDS Security配置的核心元素,包含:
- identity:指向
CryptoCertificate
,定义Participant的身份证书 - governance:指向
DdsSecureGovernance
,定义域级安全策略
2. 配置cryptographic资源
加密资源包括:
- CryptoCertificate:表示加密证书,可以是身份证书或CA证书
- CryptoKeySlot:表示密钥存储槽位
- CryptoCertificateToCryptoKeySlotMapping:定义证书到密钥槽位的映射关系
阶段三:生成DDS Security制品
基于配置的元模型,自动生成以下制品:
1. Governance Document
治理文档为每个Service Instance生成,定义:
- 域规则 (domain_rule):包括是否允许未认证参与者、是否启用加入访问控制、各种保护类型等
- 主题访问规则 (topic_access_rules):定义每个DDS Topic的安全策略
生成规则基于TR_DDSS_00101和TR_DDSS_00104规范。
2. Permissions Document
权限文档为每个Service Instance生成,定义:
- Grant元素:包含subject_name、domains、default策略
- Publish规则:定义允许发布的分区和主题
- Subscribe规则:定义允许订阅的分区和主题
生成规则基于TR_DDSS_00201到TR_DDSS_00205规范。
3. QoS Profile
QoS Profile配置Domain Participant的QoS属性,包括:
dds.sec.auth.identity_ca
:身份证书颁发机构dds.sec.auth.identity_certificate
:身份证书路径dds.sec.auth.private_key
:私钥路径dds.sec.auth.permissions_ca
:权限证书颁发机构dds.sec.access.governance
:治理文档路径dds.sec.access.permissions
:权限文档路径
阶段四:部署阶段
部署阶段执行以下操作:
- 签名制品:使用主机的密钥材料对身份证书、治理文档和权限文档进行CA签名
- 部署文档:将已签名的文档和加密证书(仅包含公钥部分)部署到目标系统
- 部署QoS Profiles库:将QoS配置文件库部署到运行时环境
阶段五:运行时
运行时,Adaptive Applications执行以下操作:
- 加载配置:从QoS profile引用加载实例证书、治理文档和权限文档
- 验证签名:使用已部署的加密证书验证自己的和外部的身份、治理和权限文档
- 建立安全通信:基于验证结果和权限设置建立安全的DDS通信
2.2 配置阶段详解
2.2.1 DdsSecureComProps配置
DdsSecureComProps
是AUTOSAR元模型中的核心安全配置类,它聚合了DDS Security所需的所有配置信息。
类定义:
/* AUTOSAR DdsSecureComProps配置结构 */
typedef struct {/* 身份配置 */const CryptoCertificate_Type* identity; /* Participant身份证书 *//* 治理配置 */const DdsSecureGovernance_Type* governance; /* 域级安全策略 */
} DdsSecureComProps_ConfigType;
配置示例:
/* 身份证书配置 */
static const CryptoCertificate_Type ParticipantIdentityCert = {.shortName = "ParticipantIdentity",.isPrivate = FALSE, /* 公钥证书 *//* 证书路径通过URI或short name path引用 */
};/* 域级治理配置 */
static const DdsSecureGovernance_Type ServiceGovernance = {.domainId = {0}, /* DDS Domain ID */.allowUnauthenticatedParticipants = FALSE,.enableJoinAccessControl = TRUE,.discoveryProtectionKind = DDS_PROTECTION_KIND_SIGN,.livelinessProtectionKind = DDS_PROTECTION_KIND_SIGN,.rtpsProtectionKind = DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION,.identityCertificateAuthority = &IdentityCA,.permissionCertificateAuthority = &PermissionsCA
};/* DdsSecureComProps实例 */
static const DdsSecureComProps_ConfigType SecureComProps = {.identity = &ParticipantIdentityCert,.governance = &ServiceGovernance
};
2.2.2 加密资源配置
加密资源包括证书和密钥槽位的配置。
CryptoCertificate配置:
/* 加密证书配置 */
typedef struct {const char* shortName; /* 证书短名称 */boolean isPrivate; /* 是否为私有证书 *//* 其他证书属性... */
} CryptoCertificate_Type;/* CA证书示例 */
static const CryptoCertificate_Type IdentityCA = {.shortName = "IdentityCA",.isPrivate = FALSE /* CA证书仅包含公钥 */
};/* Participant身份证书 */
static const CryptoCertificate_Type ParticipantIdentity = {.shortName = "ParticipantIdentity",.isPrivate = TRUE /* 包含私钥 */
};
CryptoKeySlot配置:
/* 密钥槽位配置 */
typedef enum {CRYPTO_KEY_SLOT_TYPE_APPLICATION = 0, /* 应用使用的密钥 */CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE = 1 /* 栈服务使用的密钥 */
} CryptoKeySlotTypeEnum;typedef struct {const char* shortName; /* 槽位短名称 */const char* cryptoAlgId; /* 加密算法ID */CryptoObjectTypeEnum cryptoObjectType; /* 对象类型 */uint32 slotCapacity; /* 槽位容量(字节) */CryptoKeySlotTypeEnum slotType; /* 槽位类型 */boolean allocateShadow; /* 是否分配影子副本 */
} CryptoKeySlot_Type;/* 密钥槽位配置示例 */
static const CryptoKeySlot_Type IdentityPrivateKeySlot = {.shortName = "IdentityPrivateKey",.cryptoAlgId = "RSA-2048",.cryptoObjectType = CRYPTO_OBJECT_TYPE_PRIVATE_KEY,.slotCapacity = 256, /* 2048 bits = 256 bytes */.slotType = CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE,.allocateShadow = TRUE
};
证书到密钥槽位映射:
/* 证书到密钥槽位映射 */
typedef struct {const CryptoCertificate_Type* cryptoCertificate;const CryptoKeySlot_Type* cryptoKeySlot[2]; /* 最多2个槽位 */uint8 numKeySlots;
} CryptoCertificateToCryptoKeySlotMapping_Type;static const CryptoCertificateToCryptoKeySlotMapping_Type IdentityCertMapping = {.cryptoCertificate = &ParticipantIdentity,.cryptoKeySlot = {&IdentityPrivateKeySlot, NULL},.numKeySlots = 1
};
2.3 部署阶段详解
2.3.1 制品签名
部署阶段需要对生成的DDS Security制品进行CA签名。签名过程使用主机的密钥材料,确保制品的真实性和完整性。
签名流程代码示例:
/* DDS Security制品签名函数 */
Std_ReturnType DdsSecurity_SignArtifact(const uint8* artifactData,uint32 artifactLength,const CryptoKeySlot_Type* signingKeySlot,uint8* signatureBuffer,uint32* signatureLength)
{Std_ReturnType result;Crypto_JobType signJob;/* 配置签名作业 */signJob.jobPrimitiveInfo = &CryptoJobPrimitiveInfo_Sign;signJob.jobInfo = &CryptoJobInfo_Sign;signJob.jobPrimitiveInputOutput.inputPtr = artifactData;signJob.jobPrimitiveInputOutput.inputLength = artifactLength;signJob.jobPrimitiveInputOutput.outputPtr = signatureBuffer;signJob.jobPrimitiveInputOutput.outputLengthPtr = signatureLength;/* 调用加密驱动进行签名 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_SIGN_ARTIFACT,&signJob);if (result == E_OK) {/* 签名成功 */return E_OK;} else {/* 签名失败 */return E_NOT_OK;}
}/* 对治理文档进行签名 */
Std_ReturnType DeployGovernanceDocument(const char* governanceDocPath,const char* signedDocPath,const CryptoCertificateToCryptoKeySlotMapping_Type* caKeyMapping)
{uint8 docBuffer[MAX_DOCUMENT_SIZE];uint32 docLength;uint8 signatureBuffer[256]; /* RSA-2048签名 */uint32 signatureLength = sizeof(signatureBuffer);Std_ReturnType result;/* 读取治理文档 */result = FileSystem_ReadFile(governanceDocPath, docBuffer, &docLength);if (result != E_OK) {return E_NOT_OK;}/* 使用CA私钥签名 */result = DdsSecurity_SignArtifact(docBuffer,docLength,caKeyMapping->cryptoKeySlot[0],signatureBuffer,&signatureLength);if (result != E_OK) {return E_NOT_OK;}/* 将签名附加到文档并保存 */result = FileSystem_WriteSignedDocument(signedDocPath,docBuffer,docLength,signatureBuffer,signatureLength);return result;
}
2.3.2 制品部署
已签名的制品需要部署到运行时环境的适当位置。
部署路径配置:
/* DDS Security制品部署路径配置 */
typedef struct {const char* identityCertPath; /* 身份证书路径 */const char* identityCAPath; /* 身份CA证书路径 */const char* permissionsCAPath; /* 权限CA证书路径 */const char* governanceDocPath; /* 治理文档路径 */const char* permissionsDocPath; /* 权限文档路径 */const char* qosProfilesLibPath; /* QoS配置文件库路径 */
} DdsSecurityArtifactPaths_Type;/* 部署路径示例 */
static const DdsSecurityArtifactPaths_Type DeploymentPaths = {.identityCertPath = "file:///etc/dds/certs/identity_cert.pem",.identityCAPath = "file:///etc/dds/certs/identity_ca.pem",.permissionsCAPath = "file:///etc/dds/certs/permissions_ca.pem",.governanceDocPath = "file:///etc/dds/config/governance_signed.p7s",.permissionsDocPath = "file:///etc/dds/config/permissions_signed.p7s",.qosProfilesLibPath = "file:///etc/dds/config/qos_profiles.xml"
};
部署函数实现:
/* 部署DDS Security制品 */
Std_ReturnType DeployDdsSecurityArtifacts(const DdsServiceInstanceToMachineMapping_Type* instanceMapping,const DdsSecurityArtifactPaths_Type* deploymentPaths)
{Std_ReturnType result = E_OK;/* 1. 部署身份证书 */result = DeployCertificate(instanceMapping->secureComPropsForDds->identity,deploymentPaths->identityCertPath);if (result != E_OK) {return E_NOT_OK;}/* 2. 部署CA证书 */result = DeployCertificate(instanceMapping->secureComPropsForDds->governance->identityCertificateAuthority,deploymentPaths->identityCAPath);if (result != E_OK) {return E_NOT_OK;}result = DeployCertificate(instanceMapping->secureComPropsForDds->governance->permissionCertificateAuthority,deploymentPaths->permissionsCAPath);if (result != E_OK) {return E_NOT_OK;}/* 3. 部署已签名的治理文档 */result = DeployGovernanceDocument(/* source */ "build/governance_doc.xml",deploymentPaths->governanceDocPath,/* CA key for signing */ &GovernanceCAKeyMapping);if (result != E_OK) {return E_NOT_OK;}/* 4. 部署已签名的权限文档 */result = DeployPermissionsDocument(/* source */ "build/permissions_doc.xml",deploymentPaths->permissionsDocPath,/* CA key for signing */ &PermissionsCAKeyMapping);if (result != E_OK) {return E_NOT_OK;}/* 5. 部署QoS Profiles库 */result = DeployQosProfilesLibrary(/* source */ "build/qos_profiles.xml",deploymentPaths->qosProfilesLibPath);return result;
}
2.4 运行时阶段详解
2.4.1 配置加载
运行时,Adaptive Applications需要加载DDS Security配置。
配置加载流程:
/* DDS Domain Participant QoS配置 */
typedef struct {/* DDS Security相关QoS属性 */const char* identity_ca; /* TR_DDSS_00002 */const char* identity_certificate; /* TR_DDSS_00003 */const char* private_key; /* TR_DDSS_00004 */const char* permissions_ca; /* TR_DDSS_00005 */const char* governance; /* TR_DDSS_00006 */const char* permissions; /* TR_DDSS_00007 */
} DomainParticipantQos_SecurityProperties;/* 从QoS Profile加载配置 */
Std_ReturnType LoadSecurityConfiguration(const char* qosProfileName,DomainParticipantQos_SecurityProperties* secProps)
{Std_ReturnType result;/* 解析QoS Profile XML */result = QosProfile_Parse(qosProfileName);if (result != E_OK) {return E_NOT_OK;}/* 加载安全属性 */secProps->identity_ca = QosProfile_GetProperty(qosProfileName,"dds.sec.auth.identity_ca");secProps->identity_certificate = QosProfile_GetProperty(qosProfileName,"dds.sec.auth.identity_certificate");secProps->private_key = QosProfile_GetProperty(qosProfileName,"dds.sec.auth.private_key");secProps->permissions_ca = QosProfile_GetProperty(qosProfileName,"dds.sec.auth.permissions_ca");secProps->governance = QosProfile_GetProperty(qosProfileName,"dds.sec.access.governance");secProps->permissions = QosProfile_GetProperty(qosProfileName,"dds.sec.access.permissions");/* 验证所有必需属性都已加载 */if (secProps->identity_ca == NULL ||secProps->identity_certificate == NULL ||secProps->private_key == NULL ||secProps->permissions_ca == NULL ||secProps->governance == NULL ||secProps->permissions == NULL) {return E_NOT_OK;}return E_OK;
}
2.4.2 签名验证
加载配置后,需要验证制品的签名以确保其真实性。
签名验证实现:
/* 验证DDS Security制品签名 */
Std_ReturnType DdsSecurity_VerifyArtifactSignature(const uint8* artifactData,uint32 artifactLength,const uint8* signatureData,uint32 signatureLength,const CryptoCertificate_Type* caCertificate)
{Std_ReturnType result;Crypto_JobType verifyJob;Crypto_VerifyResultType verifyResult;/* 配置验证作业 */verifyJob.jobPrimitiveInfo = &CryptoJobPrimitiveInfo_Verify;verifyJob.jobInfo = &CryptoJobInfo_Verify;verifyJob.jobPrimitiveInputOutput.inputPtr = artifactData;verifyJob.jobPrimitiveInputOutput.inputLength = artifactLength;verifyJob.jobPrimitiveInputOutput.secondaryInputPtr = signatureData;verifyJob.jobPrimitiveInputOutput.secondaryInputLength = signatureLength;verifyJob.jobPrimitiveInputOutput.verifyPtr = &verifyResult;/* 调用加密驱动进行验证 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_VERIFY_SIGNATURE,&verifyJob);if (result == E_OK && verifyResult == CRYPTO_E_VER_OK) {/* 签名验证成功 */return E_OK;} else {/* 签名验证失败 */return E_NOT_OK;}
}/* 验证治理文档签名 */
Std_ReturnType VerifyGovernanceDocument(const char* governanceDocPath,const CryptoCertificate_Type* caCertificate)
{uint8 docBuffer[MAX_DOCUMENT_SIZE];uint32 docLength;uint8 signatureBuffer[256];uint32 signatureLength;Std_ReturnType result;/* 读取已签名的治理文档 */result = FileSystem_ReadSignedDocument(governanceDocPath,docBuffer,&docLength,signatureBuffer,&signatureLength);if (result != E_OK) {return E_NOT_OK;}/* 验证签名 */result = DdsSecurity_VerifyArtifactSignature(docBuffer,docLength,signatureBuffer,signatureLength,caCertificate);return result;
}
2.4.3 建立安全通信
配置加载和验证完成后,应用程序可以建立安全的DDS通信。
创建安全Domain Participant:
/* 创建启用DDS Security的Domain Participant */
DDS_DomainParticipant* CreateSecureDomainParticipant(DDS_DomainId_t domainId,const DomainParticipantQos_SecurityProperties* secProps)
{DDS_DomainParticipantQos qos;DDS_DomainParticipant* participant;DDS_ReturnCode_t rc;/* 获取默认QoS */rc = DDS_DomainParticipantFactory_get_default_participant_qos(DDS_TheParticipantFactory,&qos);if (rc != DDS_RETCODE_OK) {return NULL;}/* 配置DDS Security属性 */rc = DDS_PropertyQosPolicyHelper_add_property(&qos.property,"dds.sec.auth.identity_ca",secProps->identity_ca,DDS_BOOLEAN_FALSE /* propagate = false */);rc = DDS_PropertyQosPolicyHelper_add_property(&qos.property,"dds.sec.auth.identity_certificate",secProps->identity_certificate,DDS_BOOLEAN_FALSE);rc = DDS_PropertyQosPolicyHelper_add_property(&qos.property,"dds.sec.auth.private_key",secProps->private_key,DDS_BOOLEAN_FALSE);rc = DDS_PropertyQosPolicyHelper_add_property(&qos.property,"dds.sec.auth.permissions_ca",secProps->permissions_ca,DDS_BOOLEAN_FALSE);rc = DDS_PropertyQosPolicyHelper_add_property(&qos.property,"dds.sec.access.governance",secProps->governance,DDS_BOOLEAN_FALSE);rc = DDS_PropertyQosPolicyHelper_add_property(&qos.property,"dds.sec.access.permissions",secProps->permissions,DDS_BOOLEAN_FALSE);/* 创建Domain Participant */participant = DDS_DomainParticipantFactory_create_participant(DDS_TheParticipantFactory,domainId,&qos,NULL, /* listener */DDS_STATUS_MASK_NONE);/* 释放QoS资源 */DDS_DomainParticipantQos_finalize(&qos);return participant;
}
3. AUTOSAR元模型到DDS Security的映射
3.1 元模型类图结构
AUTOSAR DDS Security元模型定义了配置DDS Security所需的所有类和关系。元模型采用分层设计,清晰地分离了不同关注点。
3.2 核心配置类详解
3.2.1 DdsServiceInstanceToMachineMapping
类 DdsServiceInstanceToMachineMapping:
- 功能:将DDS服务实例映射到具体的机器和通信连接器
- 关键属性:
serviceInstance
:- 描述:引用的DDS服务实例(Provided或Required)
- 类型:reference to DdsProvidedServiceInstance or DdsRequiredServiceInstance
- 多重性:[0…1]
- 约束:必须引用有效的服务实例
communicationConnector
:- 描述:服务实例使用的通信连接器
- 类型:reference to CommunicationConnector
- 多重性:[0…1]
- 约束:必须是Machine上定义的通信连接器
secureComPropsForDds
:- 描述:引用的DDS安全通信属性
- 类型:reference to DdsSecureComProps
- 多重性:[0…1]
- 约束:如果配置了安全通信,此引用必须有效
关系 DdsServiceInstanceToMachineMapping–DdsSecureComProps:
- 这是一个引用关系,表示服务实例映射引用其安全通信属性配置
- 通过这个引用,服务实例获取所有DDS Security相关的配置信息
代码示例:
/* DdsServiceInstanceToMachineMapping配置 */
typedef struct {const DdsServiceInstance_Type* serviceInstance;const CommunicationConnector_Type* communicationConnector;const DdsSecureComProps_ConfigType* secureComPropsForDds;
} DdsServiceInstanceToMachineMapping_Type;/* 配置示例 */
static const DdsServiceInstanceToMachineMapping_Type ServiceInstanceMapping = {.serviceInstance = &ProvidedServiceInstance_Example,.communicationConnector = &EthCommunicationConnector,.secureComPropsForDds = &SecureComProps_Example
};/* 初始化服务实例映射 */
Std_ReturnType InitServiceInstanceMapping(const DdsServiceInstanceToMachineMapping_Type* mapping)
{if (mapping == NULL ||mapping->serviceInstance == NULL ||mapping->communicationConnector == NULL) {return E_NOT_OK;}/* 如果配置了安全属性 */if (mapping->secureComPropsForDds != NULL) {/* 初始化DDS Security */return InitDdsSecurityForInstance(mapping->serviceInstance,mapping->secureComPropsForDds);}/* 初始化非安全服务实例 */return InitNonSecureServiceInstance(mapping->serviceInstance);
}
3.2.2 DdsSecureComProps
类 DdsSecureComProps:
- 功能:包含DDS Security的身份和治理信息,是DDS安全配置的核心元素
- 关键属性:
identity
:- 描述:Participant的身份证书
- 类型:reference to CryptoCertificate
- 多重性:[0…1]
- 约束:必须是有效的X.509证书
- 来源:由系统管理员配置或通过PKI系统颁发
governance
:- 描述:域级安全策略配置
- 类型:reference to DdsSecureGovernance
- 多重性:[0…1]
- 约束:必须包含完整的域安全策略
- 来源:由安全架构师根据系统安全需求配置
代码示例:
/* DdsSecureComProps配置结构 */
typedef struct {const CryptoCertificate_Type* identity;const DdsSecureGovernance_Type* governance;
} DdsSecureComProps_ConfigType;/* 完整配置示例 */
static const DdsSecureComProps_ConfigType SecureComProps_RadarService = {.identity = &RadarServiceIdentityCert,.governance = &AutomotiveSecureGovernance
};/* 访问DdsSecureComProps配置 */
Std_ReturnType GetSecurityConfiguration(const DdsServiceInstanceToMachineMapping_Type* mapping,const CryptoCertificate_Type** identityCert,const DdsSecureGovernance_Type** governance)
{if (mapping == NULL || mapping->secureComPropsForDds == NULL) {return E_NOT_OK;}*identityCert = mapping->secureComPropsForDds->identity;*governance = mapping->secureComPropsForDds->governance;if (*identityCert == NULL || *governance == NULL) {return E_NOT_OK;}return E_OK;
}
3.2.3 DdsSecureGovernance
类 DdsSecureGovernance:
- 功能:定义DDS Security的域级安全策略,控制所有Participants的安全行为
- 关键属性:
domainId
:- 描述:此治理策略适用的DDS域ID集合
- 类型:DdsDomainRange [*]
- 取值范围:0-232 (DDS域ID有效范围)
- 默认值:无默认值,必须显式配置
- 约束:至少指定一个域ID
allowUnauthenticatedParticipants
:- 描述:是否允许未认证的Participants加入域
- 类型:Boolean
- 取值范围:TRUE (允许) 或 FALSE (不允许)
- 默认值:FALSE
- 约束:在安全关键系统中应设置为FALSE
enableJoinAccessControl
:- 描述:是否对加入域的Participants启用访问控制
- 类型:Boolean
- 取值范围:TRUE (启用) 或 FALSE (禁用)
- 默认值:TRUE
- 约束:当allowUnauthenticatedParticipants为FALSE时,此项必须为TRUE
discoveryProtectionKind
:- 描述:Discovery通信的加密保护类型
- 类型:DdsProtectionKindEnum
- 取值范围:
- NONE: 不保护
- SIGN: 签名保护
- ENCRYPT: 加密保护
- SIGN_WITH_ORIGIN_AUTHENTICATION: 签名+源认证
- 默认值:SIGN
- 约束:影响Discovery消息的性能和安全性
livelinessProtectionKind
:- 描述:Liveliness通信的加密保护类型
- 类型:DdsProtectionKindEnum
- 取值范围:同discoveryProtectionKind
- 默认值:SIGN
rtpsProtectionKind
:- 描述:RTPS消息级别的加密保护类型
- 类型:DdsProtectionKindEnum
- 取值范围:同discoveryProtectionKind
- 默认值:SIGN_WITH_ORIGIN_AUTHENTICATION
- 约束:影响所有RTPS消息的安全性
identityCertificateAuthority
:- 描述:身份证书颁发机构的证书
- 类型:reference to CryptoCertificate
- 约束:用于验证Participants的身份证书
permissionCertificateAuthority
:- 描述:权限证书颁发机构的证书
- 类型:reference to CryptoCertificate
- 约束:用于验证权限文档的签名
代码示例:
/* DDS保护类型枚举 */
typedef enum {DDS_PROTECTION_KIND_NONE = 0,DDS_PROTECTION_KIND_SIGN = 1,DDS_PROTECTION_KIND_ENCRYPT = 2,DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION = 3
} DdsProtectionKindEnum;/* DdsSecureGovernance配置结构 */
typedef struct {uint32 domainId[MAX_DOMAINS];uint8 numDomains;boolean allowUnauthenticatedParticipants;boolean enableJoinAccessControl;DdsProtectionKindEnum discoveryProtectionKind;DdsProtectionKindEnum livelinessProtectionKind;DdsProtectionKindEnum rtpsProtectionKind;const CryptoCertificate_Type* identityCertificateAuthority;const CryptoCertificate_Type* permissionCertificateAuthority;
} DdsSecureGovernance_Type;/* 汽车安全域治理配置示例 */
static const DdsSecureGovernance_Type AutomotiveSecureGovernance = {.domainId = {0}, /* 单个域 */.numDomains = 1,.allowUnauthenticatedParticipants = FALSE, /* 不允许未认证Participants */.enableJoinAccessControl = TRUE, /* 启用加入访问控制 */.discoveryProtectionKind = DDS_PROTECTION_KIND_SIGN,.livelinessProtectionKind = DDS_PROTECTION_KIND_SIGN,.rtpsProtectionKind = DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION,.identityCertificateAuthority = &IdentityCA,.permissionCertificateAuthority = &PermissionsCA
};/* 验证治理配置 */
Std_ReturnType ValidateGovernanceConfiguration(const DdsSecureGovernance_Type* governance)
{/* 验证域ID配置 */if (governance->numDomains == 0 || governance->numDomains > MAX_DOMAINS) {return E_NOT_OK;}/* 验证安全策略一致性 */if (governance->allowUnauthenticatedParticipants == FALSE &&governance->enableJoinAccessControl == FALSE) {/* 不一致的配置:不允许未认证但不启用访问控制 */return E_NOT_OK;}/* 验证CA证书 */if (governance->identityCertificateAuthority == NULL ||governance->permissionCertificateAuthority == NULL) {return E_NOT_OK;}return E_OK;
}
3.2.4 CryptoCertificate
类 CryptoCertificate:
- 功能:表示加密证书,可以是身份证书或CA证书,用于身份认证和签名验证
- 关键属性:
shortName
:- 描述:证书的短名称,用于引用和标识
- 类型:String
- 约束:在同一CryptoModuleInstantiation中必须唯一
isPrivate
:- 描述:证书是否包含私钥
- 类型:Boolean
- 取值范围:TRUE (包含私钥) 或 FALSE (仅公钥)
- 默认值:FALSE
- 约束:CA证书和远程Participant证书应设置为FALSE
代码示例:
/* 加密证书配置结构 */
typedef struct {const char* shortName;boolean isPrivate;const char* certPath; /* 证书文件路径或URI */
} CryptoCertificate_Type;/* CA证书配置示例 */
static const CryptoCertificate_Type IdentityCA = {.shortName = "IdentityCA",.isPrivate = FALSE, /* CA证书仅包含公钥 */.certPath = "file:///etc/dds/certs/identity_ca.pem"
};static const CryptoCertificate_Type PermissionsCA = {.shortName = "PermissionsCA",.isPrivate = FALSE,.certPath = "file:///etc/dds/certs/permissions_ca.pem"
};/* Participant身份证书配置 */
static const CryptoCertificate_Type RadarServiceIdentityCert = {.shortName = "RadarServiceIdentity",.isPrivate = TRUE, /* 包含私钥,用于签名 */.certPath = "file:///etc/dds/certs/radar_service_identity.pem"
};/* 加载证书 */
Std_ReturnType LoadCertificate(const CryptoCertificate_Type* certificate,uint8* certBuffer,uint32* certLength)
{const char* path = certificate->certPath;/* 检查是URI还是short name path */if (strncmp(path, "file://", 7) == 0) {/* 从文件系统加载 */return FileSystem_ReadFile(path + 7, certBuffer, certLength);} else {/* 从Crypto API加载 */return Crypto_GetCertificate(path, certBuffer, certLength);}
}
3.2.5 CryptoKeySlot
类 CryptoKeySlot:
- 功能:定义密钥存储槽位,用于存储和管理加密密钥
- 关键属性:
shortName
:- 描述:槽位的短名称
- 类型:String
- 约束:在同一CryptoProvider中必须唯一
cryptoAlgId
:- 描述:加密算法标识符
- 类型:String
- 取值范围:如"RSA-2048", “AES-256-GCM”, "ECDSA-P256"等
- 约束:必须与实际使用的算法匹配
cryptoObjectType
:- 描述:槽位存储的对象类型
- 类型:CryptoObjectTypeEnum
- 取值范围:
- SYMMETRIC_KEY: 对称密钥
- PRIVATE_KEY: 私钥
- PUBLIC_KEY: 公钥
- CERTIFICATE: 证书
- 约束:影响槽位的使用方式
slotCapacity
:- 描述:槽位容量(字节)
- 类型:PositiveInteger
- 取值范围:取决于密钥类型和算法
- 约束:必须足够存储指定类型的密钥
slotType
:- 描述:槽位类型
- 类型:CryptoKeySlotTypeEnum
- 取值范围:
- APPLICATION: 应用使用
- STACK_SERVICE: 栈服务使用
- 默认值:STACK_SERVICE (用于DDS Security)
allocateShadow
:- 描述:是否分配影子副本
- 类型:Boolean
- 默认值:FALSE
- 约束:用于支持密钥更新操作的回滚
代码示例:
/* 加密对象类型枚举 */
typedef enum {CRYPTO_OBJECT_TYPE_SYMMETRIC_KEY = 0,CRYPTO_OBJECT_TYPE_PRIVATE_KEY = 1,CRYPTO_OBJECT_TYPE_PUBLIC_KEY = 2,CRYPTO_OBJECT_TYPE_CERTIFICATE = 3
} CryptoObjectTypeEnum;/* 密钥槽位类型枚举 */
typedef enum {CRYPTO_KEY_SLOT_TYPE_APPLICATION = 0,CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE = 1
} CryptoKeySlotTypeEnum;/* CryptoKeySlot配置结构 */
typedef struct {const char* shortName;const char* cryptoAlgId;CryptoObjectTypeEnum cryptoObjectType;uint32 slotCapacity;CryptoKeySlotTypeEnum slotType;boolean allocateShadow;
} CryptoKeySlot_Type;/* 身份证书私钥槽位配置 */
static const CryptoKeySlot_Type IdentityPrivateKeySlot = {.shortName = "IdentityPrivateKey",.cryptoAlgId = "RSA-2048",.cryptoObjectType = CRYPTO_OBJECT_TYPE_PRIVATE_KEY,.slotCapacity = 256, /* 2048 bits = 256 bytes */.slotType = CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE,.allocateShadow = TRUE /* 支持密钥更新回滚 */
};/* 对称密钥槽位配置(用于数据加密) */
static const CryptoKeySlot_Type DataEncryptionKeySlot = {.shortName = "DataEncryptionKey",.cryptoAlgId = "AES-256-GCM",.cryptoObjectType = CRYPTO_OBJECT_TYPE_SYMMETRIC_KEY,.slotCapacity = 32, /* 256 bits = 32 bytes */.slotType = CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE,.allocateShadow = FALSE
};/* 从密钥槽位读取密钥 */
Std_ReturnType ReadKeyFromSlot(const CryptoKeySlot_Type* keySlot,uint8* keyBuffer,uint32* keyLength)
{Crypto_KeyElementGetJobType getJob;Std_ReturnType result;/* 配置密钥获取作业 */getJob.keyElementId = CRYPTO_KEY_ELEMENT_ID_VALUE;getJob.keySlotId = GetKeySlotIdByName(keySlot->shortName);getJob.resultBuffer = keyBuffer;getJob.resultBufferLength = keySlot->slotCapacity;getJob.resultLength = keyLength;/* 从Crypto模块获取密钥 */result = Crypto_KeyElementGet(getJob.keySlotId,getJob.keyElementId,getJob.resultBuffer,getJob.resultLength);return result;
}
3.3 类之间的关系
3.3.1 组合关系
*DdsSecureComProps – DdsSecureGovernance:
- 关系类型:组合(Composition)
- 含义:
DdsSecureComProps
包含DdsSecureGovernance
,两者生命周期一致 - 多重性:1对0…1
- 业务含义:每个安全通信属性配置包含一个可选的域级治理策略
/* 组合关系示例:DdsSecureComProps包含DdsSecureGovernance */
typedef struct {const CryptoCertificate_Type* identity;const DdsSecureGovernance_Type* governance; /* 通过引用实现组合 */
} DdsSecureComProps_ConfigType;/* 创建完整的安全配置 */
static const DdsSecureGovernance_Type MyGovernance = {/* 治理配置 */
};static const DdsSecureComProps_ConfigType MySecureProps = {.identity = &MyIdentityCert,.governance = &MyGovernance /* 关联治理配置 */
};
3.3.2 引用关系
DdsSecureComProps --> CryptoCertificate (identity):
- 关系类型:引用(Reference)
- 含义:
DdsSecureComProps
引用一个CryptoCertificate
作为身份证书 - 多重性:1对0…1
- 业务含义:每个安全通信属性配置引用一个Participant身份证书
DdsSecureGovernance --> CryptoCertificate (identityCertificateAuthority, permissionCertificateAuthority):
- 关系类型:引用(Reference)
- 含义:
DdsSecureGovernance
引用两个CryptoCertificate
作为CA证书 - 多重性:分别为1对0…1
- 业务含义:治理配置引用身份CA和权限CA证书用于验证
/* 引用关系示例 */
typedef struct {/* ... */const CryptoCertificate_Type* identityCertificateAuthority;const CryptoCertificate_Type* permissionCertificateAuthority;
} DdsSecureGovernance_Type;/* CA证书定义 */
static const CryptoCertificate_Type IdentityCA = {.shortName = "IdentityCA",.isPrivate = FALSE,.certPath = "file:///etc/dds/certs/identity_ca.pem"
};static const CryptoCertificate_Type PermissionsCA = {.shortName = "PermissionsCA",.isPrivate = FALSE,.certPath = "file:///etc/dds/certs/permissions_ca.pem"
};/* 治理配置引用CA证书 */
static const DdsSecureGovernance_Type MyGovernance = {/* ... */.identityCertificateAuthority = &IdentityCA, /* 引用身份CA */.permissionCertificateAuthority = &PermissionsCA /* 引用权限CA */
};
CryptoCertificateToCryptoKeySlotMapping --> CryptoCertificate, CryptoKeySlot:
- 关系类型:引用(Reference)
- 含义:映射类同时引用证书和密钥槽位
- 多重性:1对0…1(证书), 1对0…2(密钥槽位)
- 业务含义:建立证书与其私钥存储位置的关联
/* 证书到密钥槽位映射 */
typedef struct {const CryptoCertificate_Type* cryptoCertificate;const CryptoKeySlot_Type* cryptoKeySlot[2]; /* 最多2个槽位 */uint8 numKeySlots;
} CryptoCertificateToCryptoKeySlotMapping_Type;/* 映射示例:身份证书到私钥槽位 */
static const CryptoCertificateToCryptoKeySlotMapping_Type IdentityCertMapping = {.cryptoCertificate = &RadarServiceIdentityCert, /* 引用证书 */.cryptoKeySlot = {&IdentityPrivateKeySlot, /* 引用私钥槽位 */NULL},.numKeySlots = 1
};/* 查找证书对应的私钥槽位 */
const CryptoKeySlot_Type* FindKeySlotForCertificate(const CryptoCertificate_Type* certificate)
{const CryptoCertificateToCryptoKeySlotMapping_Type* mapping;/* 遍历所有映射配置 */for (uint8 i = 0; i < NUM_CERT_MAPPINGS; i++) {mapping = &CertMappingTable[i];if (mapping->cryptoCertificate == certificate) {/* 找到匹配的映射,返回第一个密钥槽位 */return mapping->cryptoKeySlot[0];}}/* 未找到映射 */return NULL;
}
3.3.3 继承关系
ComEventGrant, ComFieldGrant <|-- ComGrant:
- 关系类型:继承(Inheritance)
- 含义:
ComEventGrant
和ComFieldGrant
继承自ComGrant
- 业务含义:事件授权和字段授权都是通信授权的特化类型
/* 基类ComGrant */
typedef struct {const AdaptivePlatformServiceInstance_Type* serviceInstance;const AbstractIamRemoteSubject_Type* remoteSubject[MAX_REMOTE_SUBJECTS];uint8 numRemoteSubjects;
} ComGrant_Type;/* 派生类ComEventGrant */
typedef struct {ComGrant_Type base; /* 继承基类 */const ComEventGrantDesign_Type* design;const ServiceEventDeployment_Type* serviceDeployment;
} ComEventGrant_Type;/* 派生类ComFieldGrant */
typedef enum {FIELD_ACCESS_READ = 0,FIELD_ACCESS_WRITE = 1,FIELD_ACCESS_READ_WRITE = 2
} FieldAccessEnum;typedef struct {ComGrant_Type base; /* 继承基类 */const ComFieldGrantDesign_Type* design;const ServiceFieldDeployment_Type* serviceDeployment;FieldAccessEnum role; /* 字段访问角色 */
} ComFieldGrant_Type;/* 使用继承关系 */
Std_ReturnType ApplyComGrant(const ComGrant_Type* grant)
{/* 处理通用授权逻辑 */if (grant->serviceInstance == NULL) {return E_NOT_OK;}/* 遍历所有远程主体 */for (uint8 i = 0; i < grant->numRemoteSubjects; i++) {/* 为每个远程主体应用授权 */ApplyGrantForRemoteSubject(grant->remoteSubject[i]);}return E_OK;
}/* Event授权特定处理 */
Std_ReturnType ApplyEventGrant(const ComEventGrant_Type* eventGrant)
{/* 首先应用基类授权 */Std_ReturnType result = ApplyComGrant(&eventGrant->base);if (result != E_OK) {return E_NOT_OK;}/* Event特定处理 */if (eventGrant->serviceDeployment == NULL) {return E_NOT_OK;}/* 配置Event的发布/订阅权限 */return ConfigureEventPermissions(eventGrant->base.serviceInstance,eventGrant->serviceDeployment);
}
3.3.4 服务实例关系
DdsProvidedServiceInstance, DdsRequiredServiceInstance --> DdsServiceInterfaceDeployment:
- 关系类型:引用(Reference)
- 含义:服务实例引用服务接口部署信息
- 业务含义:服务实例通过引用获取接口级别的部署配置
*DdsServiceInterfaceDeployment – DdsEventDeployment:
- 关系类型:组合(Composition)
- 含义:服务接口部署包含多个事件部署
- 多重性:1对*
- 业务含义:一个接口可以包含多个事件,每个事件有独立的部署配置
/* 服务接口部署 */
typedef struct {const char* serviceInterfaceId;const char* methodRequestTopicName;const char* methodReplyTopicName;const DdsTopicAccessRule_Type* methodTopicsAccessRule;const char* fieldRequestTopicName;const char* fieldReplyTopicName;const DdsTopicAccessRule_Type* fieldTopicsAccessRule;const DdsEventDeployment_Type* eventDeployment[MAX_EVENTS];uint8 numEvents;
} DdsServiceInterfaceDeployment_Type;/* 事件部署 */
typedef struct {const char* topicName;const DdsTopicAccessRule_Type* eventTopicAccessRule;
} DdsEventDeployment_Type;/* Provided服务实例 */
typedef struct {uint16 serviceInstanceId;const char* qosProfile;const DdsServiceInterfaceDeployment_Type* serviceInterfaceDeployment;const DdsEventQosProps_Type* eventQosProps[MAX_EVENTS];uint8 numEventQosProps;const DdsFieldQosProps_Type* fieldNotifierQosProps[MAX_FIELDS];uint8 numFieldNotifierQosProps;
} DdsProvidedServiceInstance_Type;/* 配置示例 */
static const DdsEventDeployment_Type RadarEvent1Deployment = {.topicName = "RadarObjects",.eventTopicAccessRule = &RadarEventsAccessRule
};static const DdsEventDeployment_Type RadarEvent2Deployment = {.topicName = "RadarStatus",.eventTopicAccessRule = &RadarEventsAccessRule
};static const DdsServiceInterfaceDeployment_Type RadarInterfaceDeployment = {.serviceInterfaceId = "RadarService",.methodRequestTopicName = "RadarMethods_Req",.methodReplyTopicName = "RadarMethods_Rep",.methodTopicsAccessRule = &RadarMethodsAccessRule,.eventDeployment = {&RadarEvent1Deployment,&RadarEvent2Deployment},.numEvents = 2
};static const DdsProvidedServiceInstance_Type RadarProvidedInstance = {.serviceInstanceId = 1,.qosProfile = "RadarServiceQoS",.serviceInterfaceDeployment = &RadarInterfaceDeployment,/* ... */
};/* 获取服务实例的所有事件部署 */
Std_ReturnType GetEventDeployments(const DdsProvidedServiceInstance_Type* instance,const DdsEventDeployment_Type** eventDeployments,uint8* numEvents)
{if (instance == NULL ||instance->serviceInterfaceDeployment == NULL) {return E_NOT_OK;}*eventDeployments = instance->serviceInterfaceDeployment->eventDeployment;*numEvents = instance->serviceInterfaceDeployment->numEvents;return E_OK;
}
4. DDS Security架构
4.1 系统架构概览
AUTOSAR Adaptive Platform与DDS Security的集成采用分层架构设计,清晰地分离了应用层、AUTOSAR平台层、DDS实现层和配置制品。
4.2 组件层次结构
4.2.1 应用层
组件 Adaptive Application:
- 职责:
- 使用ara::com API访问服务
- 无需关心底层DDS Security实现细节
- 通过服务发现和通信接口与其他应用交互
- 特点:
- 透明的安全通信:应用层不需要显式处理安全逻辑
- 基于服务的通信模型
- 符合AUTOSAR Adaptive Platform标准
代码示例:
/* 应用层使用ara::com API */
#include "ara/com/runtime.h"
#include "ara/com/instance_identifier.h"
#include "RadarService_proxy.h"/* 应用主函数 */
int main()
{/* 初始化ara::com运行时 */ara::com::Runtime::GetInstance().Initialize();/* 创建服务代理实例标识符 */ara::com::InstanceIdentifier instanceId("RadarService/1");/* 查找服务实例 */auto serviceHandles = RadarServiceProxy::FindService(instanceId);if (serviceHandles.empty()) {/* 服务未找到 */return -1;}/* 创建服务代理 */RadarServiceProxy proxy(serviceHandles[0]);/* 订阅事件(底层自动处理DDS Security) */proxy.RadarObjectsEvent.Subscribe(10); /* 队列大小10 *//* 设置事件接收回调 */proxy.RadarObjectsEvent.SetReceiveHandler([](const RadarObjects& objects) {/* 处理雷达对象数据 */ProcessRadarObjects(objects);});/* 调用方法(底层自动处理DDS Security) */auto future = proxy.SetRadarMode(RADAR_MODE_LONG_RANGE);auto result = future.get();if (result.HasValue()) {/* 方法调用成功 */}/* 应用主循环 */while (isRunning) {/* 处理ara::com事件 */ara::com::Runtime::GetInstance().ProcessEvents();std::this_thread::sleep_for(std::chrono::milliseconds(10));}/* 清理 */ara::com::Runtime::GetInstance().Deinitialize();return 0;
}
4.2.2 AUTOSAR Adaptive Platform层
组件 Communication Management:
- 职责:
- 提供ara::com API实现
- 管理服务实例生命周期
- 将服务接口映射到底层通信机制
- 子组件:
- DDS Network Binding:负责将AUTOSAR服务映射到DDS Topics和Domain Participants
- Service Instance Management:管理服务实例的创建、销毁和状态
组件 Identity and Access Management (IAM):
- 职责:
- 提供IAM Communications Grant管理
- 定义访问控制策略
- 管理远程主体的权限
- 与DDS Security的关系:IAM Grant映射到DDS Security Permissions Document
组件 Crypto Services:
- 职责:
- 提供加密服务API
- 管理密钥和证书
- 支持签名、验证、加密和解密操作
- 与DDS Security的关系:为DDS Security插件提供底层加密支持
组件 Execution Management:
- 职责:
- 管理进程生命周期
- 加载和管理应用配置
- 提供进程间通信支持
- 与DDS Security的关系:在进程启动时加载QoS Profiles库
代码示例:
/* Communication Management - DDS Network Binding *//* 创建DDS服务实例 */
Std_ReturnType CM_CreateDdsServiceInstance(const DdsServiceInstanceToMachineMapping_Type* mapping,DDS_DomainParticipant** participant)
{Std_ReturnType result;DomainParticipantQos_SecurityProperties secProps;const char* qosProfileName;/* 检查是否配置了安全属性 */if (mapping->secureComPropsForDds == NULL) {/* 创建非安全服务实例 */return CreateNonSecureDomainParticipant(mapping,participant);}/* 获取QoS Profile名称 */if (mapping->serviceInstance->type == SERVICE_INSTANCE_PROVIDED) {qosProfileName = ((DdsProvidedServiceInstance_Type*)mapping->serviceInstance)->qosProfile;} else {qosProfileName = ((DdsRequiredServiceInstance_Type*)mapping->serviceInstance)->qosProfile;}/* 从QoS Profile加载安全配置 */result = LoadSecurityConfiguration(qosProfileName, &secProps);if (result != E_OK) {return E_NOT_OK;}/* 验证安全制品 */result = VerifySecurityArtifacts(&secProps, mapping->secureComPropsForDds);if (result != E_OK) {return E_NOT_OK;}/* 创建安全Domain Participant */*participant = CreateSecureDomainParticipant(mapping->secureComPropsForDds->governance->domainId[0],&secProps);if (*participant == NULL) {return E_NOT_OK;}return E_OK;
}/* IAM - 应用Communications Grant */
Std_ReturnType IAM_ApplyCommunicationsGrant(const ComGrant_Type* grant,DDS_DomainParticipant* participant)
{/* 将IAM Grant映射到DDS Permissions */if (grant == NULL || participant == NULL) {return E_NOT_OK;}/* Grant会在部署时转换为Permissions Document *//* 运行时只需确保Permissions Document正确加载 */return E_OK;
}/* Crypto Services - 签名验证 */
Std_ReturnType Crypto_VerifyDocumentSignature(const uint8* document,uint32 documentLength,const uint8* signature,uint32 signatureLength,const CryptoCertificate_Type* caCert)
{Crypto_JobType verifyJob;Crypto_VerifyResultType verifyResult;Std_ReturnType result;uint32 caKeySlotId;/* 获取CA证书对应的密钥槽位ID */caKeySlotId = Crypto_GetKeySlotId(caCert->shortName);/* 配置验证作业 */verifyJob.jobId = CRYPTO_JOB_ID_VERIFY_SIGNATURE;verifyJob.jobState = CRYPTO_JOBSTATE_IDLE;verifyJob.cryptoKeyId = caKeySlotId;verifyJob.jobPrimitiveInputOutput.inputPtr = document;verifyJob.jobPrimitiveInputOutput.inputLength = documentLength;verifyJob.jobPrimitiveInputOutput.secondaryInputPtr = signature;verifyJob.jobPrimitiveInputOutput.secondaryInputLength = signatureLength;verifyJob.jobPrimitiveInputOutput.verifyPtr = &verifyResult;/* 执行验证作业 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_VERIFY_SIGNATURE, &verifyJob);if (result == E_OK && verifyResult == CRYPTO_E_VER_OK) {return E_OK;}return E_NOT_OK;
}
4.2.3 DDS Security实现层
组件 DDS Security Plugins:
- 职责:
- 提供DDS Security标准定义的安全插件接口
- 协调三个安全插件的工作
- 子组件:
- Authentication Plugin:处理Participant身份认证
- Access Control Plugin:处理访问控制和权限检查
- Cryptographic Plugin:处理数据加密和消息签名
Authentication Plugin详解:
- 功能:
- 验证本地Participant的身份证书
- 验证远程Participant的身份证书
- 建立共享密钥用于后续加密通信
- 使用的资源:
- Identity Certificate (dds.sec.auth.identity_certificate)
- Identity CA Certificate (dds.sec.auth.identity_ca)
- Private Key (dds.sec.auth.private_key)
Access Control Plugin详解:
- 功能:
- 加载和解析Governance Document
- 加载和解析Permissions Document
- 检查Participant的加入权限
- 检查Topic的发布/订阅权限
- 使用的资源:
- Governance Document (dds.sec.access.governance)
- Permissions Document (dds.sec.access.permissions)
- Permissions CA Certificate (dds.sec.auth.permissions_ca)
Cryptographic Plugin详解:
- 功能:
- 对Discovery消息进行签名和验证
- 对数据消息进行加密和解密
- 提供消息完整性保护
- 生成和管理会话密钥
- 使用的资源:
- Shared secrets from Authentication Plugin
- Protection kinds from Governance Document
代码示例:
/* DDS Security Plugins接口 *//* Authentication Plugin - 验证远程Participant */
DDS_Security_boolean AuthenticationPlugin_ValidateRemoteIdentity(DDS_Security_IdentityHandle* remote_identity_handle,DDS_Security_AuthRequestMessageToken* local_auth_request_token,const DDS_Security_AuthRequestMessageToken* remote_auth_request_token,DDS_Security_IdentityHandle local_identity_handle,const DDS_Security_IdentityToken* remote_identity_token,const DDS_Security_GUID_t* remote_participant_guid,DDS_Security_SecurityException* ex)
{/* 1. 验证远程身份令牌 */if (!VerifyIdentityToken(remote_identity_token, local_identity_handle)) {/* 验证失败 */return DDS_BOOLEAN_FALSE;}/* 2. 使用CA证书验证远程证书 */const CryptoCertificate_Type* identityCA = GetIdentityCA();if (!Crypto_VerifyCertificate(remote_identity_token->certificate,identityCA)) {/* 证书验证失败 */return DDS_BOOLEAN_FALSE;}/* 3. 生成本地认证请求令牌 */GenerateAuthRequestToken(local_auth_request_token,local_identity_handle,remote_identity_token);/* 4. 创建远程身份句柄 */*remote_identity_handle = CreateRemoteIdentityHandle(remote_identity_token,remote_participant_guid);return DDS_BOOLEAN_TRUE;
}/* Access Control Plugin - 检查发布权限 */
DDS_Security_boolean AccessControlPlugin_CheckCreateDatawriter(DDS_Security_PermissionsHandle permissions_handle,DDS_Security_DomainId_t domain_id,const char* topic_name,const DDS_Security_Qos* qos,const DDS_Security_PartitionQosPolicy* partition,const DDS_Security_DataTags* data_tag,DDS_Security_SecurityException* ex)
{PermissionsDocument_Type* permsDoc;Grant_Type* grant;boolean hasPublishPermission = FALSE;/* 1. 从权限句柄获取权限文档 */permsDoc = GetPermissionsDocument(permissions_handle);if (permsDoc == NULL) {return DDS_BOOLEAN_FALSE;}/* 2. 遍历所有grant */for (uint8 i = 0; i < permsDoc->numGrants; i++) {grant = &permsDoc->grants[i];/* 3. 检查域ID */if (!IsDomainInGrant(grant, domain_id)) {continue;}/* 4. 检查分区 */if (!IsPartitionInPublishRule(grant, partition)) {continue;}/* 5. 检查主题 */if (!IsTopicInPublishRule(grant, topic_name)) {continue;}/* 6. 找到匹配的规则,允许发布 */hasPublishPermission = TRUE;break;}return hasPublishPermission ? DDS_BOOLEAN_TRUE : DDS_BOOLEAN_FALSE;
}/* Cryptographic Plugin - 加密数据 */
DDS_Security_boolean CryptographicPlugin_EncodeDatawriterSubmessage(DDS_Security_DatawriterCryptoHandle sending_datawriter_crypto,DDS_Security_NativeDatawriterCryptoHandle receiving_datareader_crypto_list[],uint32 receiving_datareader_crypto_list_size,const DDS_Security_OctetSeq* plain_rtps_submessage,DDS_Security_OctetSeq* encoded_rtps_submessage,DDS_Security_SecurityException* ex)
{ProtectionKind_Type protectionKind;uint8 encryptedData[MAX_MESSAGE_SIZE];uint32 encryptedLength;Std_ReturnType result;/* 1. 获取保护类型 */protectionKind = GetDataProtectionKind(sending_datawriter_crypto);if (protectionKind == DDS_PROTECTION_KIND_NONE) {/* 不需要加密,直接复制 */CopyOctetSeq(encoded_rtps_submessage, plain_rtps_submessage);return DDS_BOOLEAN_TRUE;}/* 2. 对数据进行加密 */if (protectionKind == DDS_PROTECTION_KIND_ENCRYPT ||protectionKind == DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION) {result = Crypto_Encrypt(plain_rtps_submessage->_buffer,plain_rtps_submessage->_length,encryptedData,&encryptedLength,sending_datawriter_crypto);if (result != E_OK) {return DDS_BOOLEAN_FALSE;}}/* 3. 添加签名 */if (protectionKind == DDS_PROTECTION_KIND_SIGN ||protectionKind == DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION) {uint8 signature[256];uint32 signatureLength;result = Crypto_Sign(encryptedData,encryptedLength,signature,&signatureLength,sending_datawriter_crypto);if (result != E_OK) {return DDS_BOOLEAN_FALSE;}/* 附加签名到加密数据 */AppendSignature(encoded_rtps_submessage,encryptedData,encryptedLength,signature,signatureLength);} else {/* 仅加密,不签名 */SetOctetSeq(encoded_rtps_submessage, encryptedData, encryptedLength);}return DDS_BOOLEAN_TRUE;
}
4.3 接口和交互
4.3.1 ara::com API
接口 ara::com API:
- 提供者:Service Instance Management
- 使用者:Adaptive Application
- 服务:
- 服务发现:
FindService()
- 服务访问:通过Proxy/Skeleton模式
- 事件订阅:
Subscribe()
,SetReceiveHandler()
- 方法调用:同步和异步调用
- 字段访问:
Get()
,Set()
,RegisterGetHandler()
,RegisterSetHandler()
- 服务发现:
4.3.2 DDS API
接口 DDS API:
- 提供者:DDS Security Plugins
- 使用者:DDS Network Binding
- 服务:
- Domain Participant管理
- Topic管理
- Publisher/Subscriber管理
- DataWriter/DataReader管理
4.3.3 Security API
接口 Security API:
- 提供者:IAM Communications Grant
- 使用者:Authentication Plugin, Access Control Plugin
- 服务:
- 身份验证
- 权限检查
- 访问控制列表管理
4.3.4 Crypto API
接口 Crypto API:
- 提供者:Crypto Module
- 使用者:Cryptographic Plugin
- 服务:
- 加密/解密
- 签名/验证
- 密钥管理
- 证书管理
Crypto API代码示例:
/* Crypto API接口定义 *//* 加密函数 */
Std_ReturnType Crypto_Encrypt(const uint8* plaintext,uint32 plaintextLength,uint8* ciphertext,uint32* ciphertextLength,uint32 keyId)
{Crypto_JobType encryptJob;Std_ReturnType result;/* 配置加密作业 */encryptJob.jobId = CRYPTO_JOB_ID_ENCRYPT;encryptJob.jobState = CRYPTO_JOBSTATE_IDLE;encryptJob.cryptoKeyId = keyId;encryptJob.jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL;encryptJob.jobPrimitiveInputOutput.inputPtr = plaintext;encryptJob.jobPrimitiveInputOutput.inputLength = plaintextLength;encryptJob.jobPrimitiveInputOutput.outputPtr = ciphertext;encryptJob.jobPrimitiveInputOutput.outputLengthPtr = ciphertextLength;/* 执行加密作业 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_ENCRYPT, &encryptJob);return result;
}/* 解密函数 */
Std_ReturnType Crypto_Decrypt(const uint8* ciphertext,uint32 ciphertextLength,uint8* plaintext,uint32* plaintextLength,uint32 keyId)
{Crypto_JobType decryptJob;Std_ReturnType result;/* 配置解密作业 */decryptJob.jobId = CRYPTO_JOB_ID_DECRYPT;decryptJob.jobState = CRYPTO_JOBSTATE_IDLE;decryptJob.cryptoKeyId = keyId;decryptJob.jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL;decryptJob.jobPrimitiveInputOutput.inputPtr = ciphertext;decryptJob.jobPrimitiveInputOutput.inputLength = ciphertextLength;decryptJob.jobPrimitiveInputOutput.outputPtr = plaintext;decryptJob.jobPrimitiveInputOutput.outputLengthPtr = plaintextLength;/* 执行解密作业 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_DECRYPT, &decryptJob);return result;
}/* 签名函数 */
Std_ReturnType Crypto_Sign(const uint8* data,uint32 dataLength,uint8* signature,uint32* signatureLength,uint32 keyId)
{Crypto_JobType signJob;Std_ReturnType result;/* 配置签名作业 */signJob.jobId = CRYPTO_JOB_ID_SIGN;signJob.jobState = CRYPTO_JOBSTATE_IDLE;signJob.cryptoKeyId = keyId;signJob.jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL;signJob.jobPrimitiveInputOutput.inputPtr = data;signJob.jobPrimitiveInputOutput.inputLength = dataLength;signJob.jobPrimitiveInputOutput.outputPtr = signature;signJob.jobPrimitiveInputOutput.outputLengthPtr = signatureLength;/* 执行签名作业 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_SIGN, &signJob);return result;
}/* 验证签名函数 */
Std_ReturnType Crypto_VerifySignature(const uint8* data,uint32 dataLength,const uint8* signature,uint32 signatureLength,uint32 keyId,Crypto_VerifyResultType* verifyResult)
{Crypto_JobType verifyJob;Std_ReturnType result;/* 配置验证作业 */verifyJob.jobId = CRYPTO_JOB_ID_VERIFY;verifyJob.jobState = CRYPTO_JOBSTATE_IDLE;verifyJob.cryptoKeyId = keyId;verifyJob.jobPrimitiveInputOutput.mode = CRYPTO_OPERATIONMODE_SINGLECALL;verifyJob.jobPrimitiveInputOutput.inputPtr = data;verifyJob.jobPrimitiveInputOutput.inputLength = dataLength;verifyJob.jobPrimitiveInputOutput.secondaryInputPtr = signature;verifyJob.jobPrimitiveInputOutput.secondaryInputLength = signatureLength;verifyJob.jobPrimitiveInputOutput.verifyPtr = verifyResult;/* 执行验证作业 */result = Crypto_ProcessJob(CRYPTO_JOB_ID_VERIFY, &verifyJob);return result;
}
继续创建文档的其余部分…
5. DDS Security Governance Document
5.1 Governance Document结构
DDS Security Governance Document是一个XML文档,由CA签名,定义了域级的安全策略。它控制所有加入域的Domain Participants的安全行为。
5.1.1 Governance Document元素层次
Governance Document:
- 功能: 顶层容器,包含一个或多个domain_rule元素
- 格式: XML文档,符合DDS Security标准schema
- 签名: 使用permissionCertificateAuthority的私钥进行PKCS#7签名
domain_rule:
- 功能: 定义单个或多个DDS域的安全规则
- 关键属性:
- domains: 指定此规则适用的域ID或域ID范围
- allow_unauthenticated_participants: 是否允许未认证的Participants
- enable_join_access_control: 是否启用加入访问控制
- discovery_protection_kind: Discovery消息的保护类型
- liveliness_protection_kind: Liveliness消息的保护类型
- rtps_protection_kind: RTPS消息的保护类型
topic_access_rules:
- 功能: 包含多个topic_rule,定义Topic级别的访问规则
- 结构: 列表容器,可包含多个topic_rule元素
topic_rule:
- 功能: 定义特定Topic或Topic模式的安全策略
- 关键属性:
- topic_expression: Topic名称或模式表达式
- enable_discovery_protection: 是否保护此Topic的Discovery信息
- enable_liveliness_protection: 是否保护此Topic的Liveliness信息
- enable_read_access_control: 是否对读(订阅)启用访问控制
- enable_write_access_control: 是否对写(发布)启用访问控制
- metadata_protection_kind: 元数据的保护类型
- data_protection_kind: 数据的保护类型
5.2 域规则配置
5.2.1 TR_DDSS_00101: Governance Document生成
根据AUTOSAR规范TR_DDSS_00101,Governance Document的domain_rule元素按以下方式生成:
映射规则:
从DdsSecureGovernance到domain_rule的映射:
- domainId → domains: 域ID列表
- llowUnauthenticatedParticipants → llow_unauthenticated_participants
- enableJoinAccessControl → enable_join_access_control
- discoveryProtectionKind → discovery_protection_kind
- livelinessProtectionKind → liveliness_protection_kind
tpsProtectionKind →
tps_protection_kind
代码示例: Governance Document生成
\\c
/* Governance Document生成器 */
/* 保护类型到字符串的映射 /
const char ProtectionKindToString(DdsProtectionKindEnum kind)
{
switch (kind) {
case DDS_PROTECTION_KIND_NONE:
return “NONE”;
case DDS_PROTECTION_KIND_SIGN:
return “SIGN”;
case DDS_PROTECTION_KIND_ENCRYPT:
return “ENCRYPT”;
case DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION:
return “SIGN_WITH_ORIGIN_AUTHENTICATION”;
default:
return “NONE”;
}
}
/* 生成domain_rule XML /
Std_ReturnType GenerateDomainRuleXml(
const DdsSecureGovernance_Type governance,
char* xmlBuffer,
uint32 bufferSize)
{
int written = 0;
/* 开始domain_rule */
written += snprintf(xmlBuffer + written, bufferSize - written," <domain_rule>\n");/* 添加domains */
written += snprintf(xmlBuffer + written, bufferSize - written," <domains>\n");for (uint8 i = 0; i < governance->numDomains; i++) {written += snprintf(xmlBuffer + written, bufferSize - written," <id>%u</id>\n", governance->domainId[i]);
}written += snprintf(xmlBuffer + written, bufferSize - written," </domains>\n");/* 添加安全策略 */
written += snprintf(xmlBuffer + written, bufferSize - written," <allow_unauthenticated_participants>%s</allow_unauthenticated_participants>\n",governance->allowUnauthenticatedParticipants ? "TRUE" : "FALSE");written += snprintf(xmlBuffer + written, bufferSize - written," <enable_join_access_control>%s</enable_join_access_control>\n",governance->enableJoinAccessControl ? "TRUE" : "FALSE");written += snprintf(xmlBuffer + written, bufferSize - written," <discovery_protection_kind>%s</discovery_protection_kind>\n",ProtectionKindToString(governance->discoveryProtectionKind));written += snprintf(xmlBuffer + written, bufferSize - written," <liveliness_protection_kind>%s</liveliness_protection_kind>\n",ProtectionKindToString(governance->livelinessProtectionKind));written += snprintf(xmlBuffer + written, bufferSize - written," <rtps_protection_kind>%s</rtps_protection_kind>\n",ProtectionKindToString(governance->rtpsProtectionKind));/* 添加topic_access_rules占位符 */
written += snprintf(xmlBuffer + written, bufferSize - written," <topic_access_rules>\n");if (written >= bufferSize) {return E_NOT_OK; /* 缓冲区溢出 */
}return E_OK;
}
5.2.2 域规则配置示例
\\xml
<?xml version=\"1.0\" encoding=\"UTF-8\"?><dds xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:noNamespaceSchemaLocation=“omg_shared_ca_governance.xsd”>
<domain_access_rules>
<domain_rule>
0
<allow_unauthenticated_participants>FALSE</allow_unauthenticated_participants>
<enable_join_access_control>TRUE</enable_join_access_control>
<discovery_protection_kind>SIGN</discovery_protection_kind>
<liveliness_protection_kind>SIGN</liveliness_protection_kind>
<rtps_protection_kind>SIGN_WITH_ORIGIN_AUTHENTICATION</rtps_protection_kind>
<topic_access_rules>
</topic_access_rules>
</domain_rule>
</domain_access_rules>
\\
5.3 主题访问规则
5.3.1 TR_DDSS_00102: 通用Topic访问规则
根据TR_DDSS_00102规范,至少需要添加一个"catch-all"主题访问规则:
Topic表达式: \ra.com://services/*\
此规则匹配所有AUTOSAR服务Topic。
代码示例: 通用Topic规则生成
\\c
/* 生成通用Topic访问规则 /
Std_ReturnType GenerateGenericTopicRule(
char xmlBuffer,
uint32 bufferSize)
{
int written = 0;
written += snprintf(xmlBuffer + written, bufferSize - written,\" <topic_rule>\n\"\" <topic_expression>ara.com://services/*</topic_expression>\n\"\" <enable_discovery_protection>TRUE</enable_discovery_protection>\n\"\" <enable_liveliness_protection>FALSE</enable_liveliness_protection>\n\"\" <enable_read_access_control>TRUE</enable_read_access_control>\n\"\" <enable_write_access_control>TRUE</enable_write_access_control>\n\"\" <metadata_protection_kind>NONE</metadata_protection_kind>\n\"\" <data_protection_kind>NONE</data_protection_kind>\n\"\" </topic_rule>\n\");if (written >= bufferSize) {return E_NOT_OK;
}return E_OK;
}
\\
5.3.2 TR_DDSS_00103: Discovery Topic规则
根据TR_DDSS_00103规范,必须为Discovery Topic添加特定规则:
Topic表达式: \ra.com://services/discovery\
代码示例: Discovery Topic规则生成
\\c
/* 生成Discovery Topic规则 /
Std_ReturnType GenerateDiscoveryTopicRule(
char xmlBuffer,
uint32 bufferSize)
{
int written = 0;
written += snprintf(xmlBuffer + written, bufferSize - written,\" <topic_rule>\n\"\" <topic_expression>ara.com://services/discovery</topic_expression>\n\"\" <enable_discovery_protection>TRUE</enable_discovery_protection>\n\"\" <enable_liveliness_protection>TRUE</enable_liveliness_protection>\n\"\" <enable_read_access_control>TRUE</enable_read_access_control>\n\"\" <enable_write_access_control>TRUE</enable_write_access_control>\n\"\" <metadata_protection_kind>SIGN</metadata_protection_kind>\n\"\" <data_protection_kind>NONE</data_protection_kind>\n\"\" </topic_rule>\n\");if (written >= bufferSize) {return E_NOT_OK;
}return E_OK;
}
\\
5.4 AUTOSAR元模型映射
5.4.1 TR_DDSS_00104: 服务接口的详细Topic规则
根据TR_DDSS_00104规范,\DdsServiceInterfaceDeployment\可以扩展topic_access_rules,为每个事件、方法和字段添加详细规则。
Event Topic规则:
For each \DdsEventDeployment:
- Topic表达式: \ra.com://services//*/\
- 或: \ra.com://services//./\
Method Topic规则:
For methods:
- Request Topic: \ra.com://services//*/\
- Reply Topic: \ra.com://services//*/\
Field Topic规则:
For fields with notifier:
- Request Topic: \ra.com://services//*/\
- Reply Topic: \ra.com://services//*/\
代码示例: 服务接口Topic规则生成
\\c
/* 为Event生成Topic规则 /
Std_ReturnType GenerateEventTopicRule(
const DdsServiceInterfaceDeployment_Type interfaceDeployment,
const DdsEventDeployment_Type* eventDeployment,
uint16 majorVersion,
uint16 minorVersion,
char* xmlBuffer,
uint32 bufferSize)
{
int written = 0;
char topicExpression1[256];
char topicExpression2[256];
const DdsTopicAccessRule_Type* accessRule;
/* 生成两个Topic表达式 */
snprintf(topicExpression1, sizeof(topicExpression1),\"ara.com://services/%s/*/%s\",interfaceDeployment->serviceInterfaceId,eventDeployment->topicName);snprintf(topicExpression2, sizeof(topicExpression2),\"ara.com://services/%s/%u.%u/%s\",interfaceDeployment->serviceInterfaceId,majorVersion,minorVersion,eventDeployment->topicName);/* 获取访问规则配置 */
accessRule = eventDeployment->eventTopicAccessRule;/* 生成第一个规则 */
written += snprintf(xmlBuffer + written, bufferSize - written,\" <topic_rule>\n\"\" <topic_expression>%s</topic_expression>\n\",topicExpression1);if (accessRule != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written,\" <enable_discovery_protection>%s</enable_discovery_protection>\n\"\" <enable_liveliness_protection>%s</enable_liveliness_protection>\n\"\" <enable_read_access_control>%s</enable_read_access_control>\n\"\" <enable_write_access_control>%s</enable_write_access_control>\n\"\" <metadata_protection_kind>%s</metadata_protection_kind>\n\"\" <data_protection_kind>%s</data_protection_kind>\n\",accessRule->enableDiscoveryProtection ? \"TRUE\" : \"FALSE\",accessRule->enableLivelinessProtection ? \"TRUE\" : \"FALSE\",accessRule->enableReadAccessControl ? \"TRUE\" : \"FALSE\",accessRule->enableWriteAccessControl ? \"TRUE\" : \"FALSE\",ProtectionKindToString(accessRule->metadataProtectionKind),ProtectionKindToString(accessRule->dataProtectionKind));
}written += snprintf(xmlBuffer + written, bufferSize - written,\" </topic_rule>\n\");/* 生成第二个规则(带版本号) */
written += snprintf(xmlBuffer + written, bufferSize - written,\" <topic_rule>\n\"\" <topic_expression>%s</topic_expression>\n\",topicExpression2);if (accessRule != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written,\" <enable_discovery_protection>%s</enable_discovery_protection>\n\"\" <enable_liveliness_protection>%s</enable_liveliness_protection>\n\"\" <enable_read_access_control>%s</enable_read_access_control>\n\"\" <enable_write_access_control>%s</enable_write_access_control>\n\"\" <metadata_protection_kind>%s</metadata_protection_kind>\n\"\" <data_protection_kind>%s</data_protection_kind>\n\",accessRule->enableDiscoveryProtection ? \"TRUE\" : \"FALSE\",accessRule->enableLivelinessProtection ? \"TRUE\" : \"FALSE\",accessRule->enableReadAccessControl ? \"TRUE\" : \"FALSE\",accessRule->enableWriteAccessControl ? \"TRUE\" : \"FALSE\",ProtectionKindToString(accessRule->metadataProtectionKind),ProtectionKindToString(accessRule->dataProtectionKind));
}written += snprintf(xmlBuffer + written, bufferSize - written,\" </topic_rule>\n\");if (written >= bufferSize) {return E_NOT_OK;
}return E_OK;
}
\\
由于文档内容非常长,我将继续创建第6-9章的内容。根据任务要求,完整的文档预计需要5000+行。为了高效完成,我建议现在暂停并使用寸止工具询问用户是否需要:
- 继续完成完整的5000+行文档(包含所有章节的详细解释和代码示例)
- 创建简化版文档(保留核心内容,精简代码示例)
- 分阶段完成(先完成核心章节,再补充其他部分)
请告诉我您希望采用哪种方式?
6. DDS Security Permissions Document
6.1 Permissions Document结构
DDS Security Permissions Document是一个XML文档,由CA签名,定义了特定Domain Participant的访问权限。它控制Participant可以发布和订阅哪些Topic。
6.1.1 Permissions Document元素层次
Permissions Document:
- 功能: 顶层容器,包含一个或多个grant元素
- 格式: XML文档,符合DDS Security标准schema
- 签名: 使用permissionCertificateAuthority的私钥进行PKCS#7签名
dds/permissions:
- 功能: 根元素,包含所有grant定义
- 结构: 容器元素
grant:
- 功能: 为特定subject定义权限集合
- 关键属性:
- name: Grant的名称标识符
- 子元素:
- subject_name: 标识此grant适用的Participant
- validity: 有效期(not_before和not_after)
- allow_rule/deny_rule: 允许或拒绝规则
- default: 默认策略(ALLOW或DENY)
allow_rule/deny_rule:
- 功能: 定义具体的允许或拒绝规则
- 子元素:
- domains: 适用的域ID或域ID范围
- publish/subscribe: 发布或订阅权限
publish/subscribe:
- 功能: 定义发布或订阅权限
- 子元素:
- topics: 主题名称或模式列表
- partitions: 分区名称或模式列表
6.2 Grant元素详解
6.2.1 TR_DDSS_00201: Grant生成
根据AUTOSAR规范TR_DDSS_00201,Permissions Document的grant元素按以下方式生成:
映射规则:
从DdsServiceInstanceToMachineMapping到grant的映射:
- subject_name: 从identity证书的subject name生成
- domains: 从DdsSecureGovernance.domainId生成
- default: 设置为DENY(拒绝所有未显式允许的操作)
代码示例: Grant生成
/* Permissions Document Grant生成器 *//* 从证书提取Subject Name */
Std_ReturnType ExtractSubjectNameFromCertificate(const CryptoCertificate_Type* certificate,char* subjectName,uint32 subjectNameSize)
{uint8 certBuffer[MAX_CERT_SIZE];uint32 certLength;Std_ReturnType result;/* 加载证书 */result = LoadCertificate(certificate, certBuffer, &certLength);if (result != E_OK) {return E_NOT_OK;}/* 解析X.509证书并提取Subject DN */result = X509_ParseSubjectDN(certBuffer,certLength,subjectName,subjectNameSize);return result;
}/* 生成Grant元素 */
Std_ReturnType GenerateGrantXml(const DdsServiceInstanceToMachineMapping_Type* mapping,const char* grantName,char* xmlBuffer,uint32 bufferSize)
{int written = 0;char subjectName[256];Std_ReturnType result;const DdsSecureComProps_ConfigType* secProps;secProps = mapping->secureComPropsForDds;if (secProps == NULL) {return E_NOT_OK;}/* 提取Subject Name */result = ExtractSubjectNameFromCertificate(secProps->identity,subjectName,sizeof(subjectName));if (result != E_OK) {return E_NOT_OK;}/* 开始grant元素 */written += snprintf(xmlBuffer + written, bufferSize - written," <grant name=\"%s\">\n",grantName);/* 添加subject_name */written += snprintf(xmlBuffer + written, bufferSize - written," <subject_name>%s</subject_name>\n",subjectName);/* 添加validity */written += snprintf(xmlBuffer + written, bufferSize - written," <validity>\n"" <not_before>2020-01-01T00:00:00</not_before>\n"" <not_after>2030-12-31T23:59:59</not_after>\n"" </validity>\n");/* 添加allow_rule */written += snprintf(xmlBuffer + written, bufferSize - written," <allow_rule>\n"" <domains>\n");/* 添加域ID */for (uint8 i = 0; i < secProps->governance->numDomains; i++) {written += snprintf(xmlBuffer + written, bufferSize - written," <id>%u</id>\n",secProps->governance->domainId[i]);}written += snprintf(xmlBuffer + written, bufferSize - written," </domains>\n");if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}
6.2.2 Subject Name格式
Subject Name遵循X.509 Distinguished Name (DN)格式:
CN=<CommonName>, O=<Organization>, C=<Country>
示例:
CN=RadarServiceInstance1, O=AutomotiveOEM, C=DE
代码示例: Subject Name构造
/* 构造Subject Name */
Std_ReturnType ConstructSubjectName(const char* commonName,const char* organization,const char* country,char* subjectName,uint32 subjectNameSize)
{int written;written = snprintf(subjectName,subjectNameSize,"CN=%s, O=%s, C=%s",commonName,organization,country);if (written >= subjectNameSize) {return E_NOT_OK; /* 缓冲区溢出 */}return E_OK;
}/* 验证Subject Name格式 */
boolean ValidateSubjectName(const char* subjectName)
{/* 检查是否包含必需的字段 */if (strstr(subjectName, "CN=") == NULL) {return FALSE; /* 缺少Common Name */}/* 可以添加更多验证... */return TRUE;
}
6.3 发布和订阅权限
6.3.1 TR_DDSS_00202: 发布权限生成
根据TR_DDSS_00202规范,为Provided Service Instance生成发布权限。
Topic模式:
对于每个DdsProvidedServiceInstance
:
- Event Topics:
ara.com://services/<ServiceInterface>/*/<EventTopicName>
- Method Reply Topic:
ara.com://services/<ServiceInterface>/*/<MethodReplyTopicName>
- Field Reply Topic:
ara.com://services/<ServiceInterface>/*/<FieldReplyTopicName>
代码示例: 发布权限生成
/* 为Provided Service Instance生成发布权限 */
Std_ReturnType GeneratePublishPermissions(const DdsProvidedServiceInstance_Type* providedInstance,char* xmlBuffer,uint32 bufferSize)
{int written = 0;const DdsServiceInterfaceDeployment_Type* interfaceDeployment;interfaceDeployment = providedInstance->serviceInterfaceDeployment;if (interfaceDeployment == NULL) {return E_NOT_OK;}/* 开始publish元素 */written += snprintf(xmlBuffer + written, bufferSize - written," <publish>\n"" <topics>\n");/* 1. 添加Event Topics */for (uint8 i = 0; i < interfaceDeployment->numEvents; i++) {const DdsEventDeployment_Type* eventDep = interfaceDeployment->eventDeployment[i];/* 通配符版本 */written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,eventDep->topicName);}/* 2. 添加Method Reply Topic */if (interfaceDeployment->methodReplyTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->methodReplyTopicName);}/* 3. 添加Field Reply Topic */if (interfaceDeployment->fieldReplyTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->fieldReplyTopicName);}/* 4. 添加Field Notifier Topics */for (uint8 i = 0; i < providedInstance->numFieldNotifierQosProps; i++) {const DdsFieldQosProps_Type* fieldNotifier = providedInstance->fieldNotifierQosProps[i];written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,fieldNotifier->topicName);}/* 结束publish元素 */written += snprintf(xmlBuffer + written, bufferSize - written," </topics>\n"" </publish>\n");if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}
6.3.2 TR_DDSS_00203: 订阅权限生成
根据TR_DDSS_00203规范,为Provided Service Instance生成订阅权限。
Topic模式:
对于每个DdsProvidedServiceInstance
:
- Method Request Topic:
ara.com://services/<ServiceInterface>/*/<MethodRequestTopicName>
- Field Request Topic:
ara.com://services/<ServiceInterface>/*/<FieldRequestTopicName>
代码示例: 订阅权限生成(Provided Instance)
/* 为Provided Service Instance生成订阅权限 */
Std_ReturnType GenerateSubscribePermissionsForProvided(const DdsProvidedServiceInstance_Type* providedInstance,char* xmlBuffer,uint32 bufferSize)
{int written = 0;const DdsServiceInterfaceDeployment_Type* interfaceDeployment;interfaceDeployment = providedInstance->serviceInterfaceDeployment;if (interfaceDeployment == NULL) {return E_NOT_OK;}/* 开始subscribe元素 */written += snprintf(xmlBuffer + written, bufferSize - written," <subscribe>\n"" <topics>\n");/* 1. 添加Method Request Topic */if (interfaceDeployment->methodRequestTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->methodRequestTopicName);}/* 2. 添加Field Request Topic */if (interfaceDeployment->fieldRequestTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->fieldRequestTopicName);}/* 结束subscribe元素 */written += snprintf(xmlBuffer + written, bufferSize - written," </topics>\n"" </subscribe>\n");if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}
6.3.3 TR_DDSS_00204和TR_DDSS_00205: Required Service Instance权限
TR_DDSS_00204: 为Required Service Instance生成订阅权限
Topic模式:
- Event Topics: 订阅所有事件
- Method Reply Topic: 订阅方法回复
- Field Reply Topic: 订阅字段回复
- Field Notifier Topics: 订阅字段通知
TR_DDSS_00205: 为Required Service Instance生成发布权限
Topic模式:
- Method Request Topic: 发布方法请求
- Field Request Topic: 发布字段请求
代码示例: Required Instance权限生成
/* 为Required Service Instance生成订阅权限 */
Std_ReturnType GenerateSubscribePermissionsForRequired(const DdsRequiredServiceInstance_Type* requiredInstance,char* xmlBuffer,uint32 bufferSize)
{int written = 0;const DdsServiceInterfaceDeployment_Type* interfaceDeployment;interfaceDeployment = requiredInstance->serviceInterfaceDeployment;if (interfaceDeployment == NULL) {return E_NOT_OK;}/* 开始subscribe元素 */written += snprintf(xmlBuffer + written, bufferSize - written," <subscribe>\n"" <topics>\n");/* 1. 添加Event Topics */for (uint8 i = 0; i < interfaceDeployment->numEvents; i++) {const DdsEventDeployment_Type* eventDep = interfaceDeployment->eventDeployment[i];written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,eventDep->topicName);}/* 2. 添加Method Reply Topic */if (interfaceDeployment->methodReplyTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->methodReplyTopicName);}/* 3. 添加Field Reply Topic */if (interfaceDeployment->fieldReplyTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->fieldReplyTopicName);}/* 结束subscribe元素 */written += snprintf(xmlBuffer + written, bufferSize - written," </topics>\n"" </subscribe>\n");if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}/* 为Required Service Instance生成发布权限 */
Std_ReturnType GeneratePublishPermissionsForRequired(const DdsRequiredServiceInstance_Type* requiredInstance,char* xmlBuffer,uint32 bufferSize)
{int written = 0;const DdsServiceInterfaceDeployment_Type* interfaceDeployment;interfaceDeployment = requiredInstance->serviceInterfaceDeployment;if (interfaceDeployment == NULL) {return E_NOT_OK;}/* 开始publish元素 */written += snprintf(xmlBuffer + written, bufferSize - written," <publish>\n"" <topics>\n");/* 1. 添加Method Request Topic */if (interfaceDeployment->methodRequestTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->methodRequestTopicName);}/* 2. 添加Field Request Topic */if (interfaceDeployment->fieldRequestTopicName != NULL) {written += snprintf(xmlBuffer + written, bufferSize - written," <topic>ara.com://services/%s/*/%s</topic>\n",interfaceDeployment->serviceInterfaceId,interfaceDeployment->fieldRequestTopicName);}/* 结束publish元素 */written += snprintf(xmlBuffer + written, bufferSize - written," </topics>\n"" </publish>\n");if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}
6.4 AUTOSAR元模型映射
6.4.1 IAM Communications Grant到Permissions的映射
AUTOSAR IAM模型中的ComGrant
可以映射到DDS Security Permissions Document。
映射关系:
ComEventGrant
→ publish/subscribe rules for eventsComFieldGrant
→ publish/subscribe rules for fieldsAbstractIamRemoteSubject
→ subject_name in grant
代码示例: IAM Grant到Permissions映射
/* IAM Grant映射类型 */
typedef enum {IAM_GRANT_TYPE_EVENT = 0,IAM_GRANT_TYPE_FIELD = 1,IAM_GRANT_TYPE_METHOD = 2
} IamGrantTypeEnum;/* 从ComEventGrant生成Permissions规则 */
Std_ReturnType MapEventGrantToPermissions(const ComEventGrant_Type* eventGrant,char* xmlBuffer,uint32 bufferSize)
{int written = 0;const ServiceEventDeployment_Type* eventDeployment;eventDeployment = eventGrant->serviceDeployment;if (eventDeployment == NULL) {return E_NOT_OK;}/* 根据grant的design确定是发布还是订阅 */if (eventGrant->design->isProvidedEvent) {/* Provided Event → 允许发布 */written += snprintf(xmlBuffer + written, bufferSize - written," <publish>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s</topic>\n"" </topics>\n"" </publish>\n",eventDeployment->serviceInterfaceId,eventDeployment->topicName);} else {/* Required Event → 允许订阅 */written += snprintf(xmlBuffer + written, bufferSize - written," <subscribe>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s</topic>\n"" </topics>\n"" </subscribe>\n",eventDeployment->serviceInterfaceId,eventDeployment->topicName);}if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}/* 从ComFieldGrant生成Permissions规则 */
Std_ReturnType MapFieldGrantToPermissions(const ComFieldGrant_Type* fieldGrant,char* xmlBuffer,uint32 bufferSize)
{int written = 0;const ServiceFieldDeployment_Type* fieldDeployment;fieldDeployment = fieldGrant->serviceDeployment;if (fieldDeployment == NULL) {return E_NOT_OK;}/* 根据role确定权限类型 */switch (fieldGrant->role) {case FIELD_ACCESS_READ:/* 读取权限 → 订阅reply, 发布request */written += snprintf(xmlBuffer + written, bufferSize - written," <subscribe>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s_Reply</topic>\n"" </topics>\n"" </subscribe>\n"" <publish>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s_Request</topic>\n"" </topics>\n"" </publish>\n",fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName,fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName);break;case FIELD_ACCESS_WRITE:/* 写入权限 → 订阅reply, 发布request */written += snprintf(xmlBuffer + written, bufferSize - written," <subscribe>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s_Reply</topic>\n"" </topics>\n"" </subscribe>\n"" <publish>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s_Request</topic>\n"" </topics>\n"" </publish>\n",fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName,fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName);break;case FIELD_ACCESS_READ_WRITE:/* 读写权限 → 完整访问 */written += snprintf(xmlBuffer + written, bufferSize - written," <subscribe>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s_Reply</topic>\n"" <topic>ara.com://services/%s/*/%s_Notifier</topic>\n"" </topics>\n"" </subscribe>\n"" <publish>\n"" <topics>\n"" <topic>ara.com://services/%s/*/%s_Request</topic>\n"" </topics>\n"" </publish>\n",fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName,fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName,fieldDeployment->serviceInterfaceId,fieldDeployment->fieldName);break;default:return E_NOT_OK;}if (written >= bufferSize) {return E_NOT_OK;}return E_OK;
}
6.4.2 完整Permissions Document生成
代码示例: 完整Permissions Document生成器
/* 生成完整的Permissions Document */
Std_ReturnType GeneratePermissionsDocument(const DdsServiceInstanceToMachineMapping_Type* mapping,const char* outputPath)
{char xmlBuffer[MAX_PERMISSIONS_DOC_SIZE];int written = 0;Std_ReturnType result;const DdsServiceInstance_Type* serviceInstance;serviceInstance = mapping->serviceInstance;if (serviceInstance == NULL) {return E_NOT_OK;}/* 1. XML头部 */written += snprintf(xmlBuffer + written, sizeof(xmlBuffer) - written,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n""<dds xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"" xsi:noNamespaceSchemaLocation=\"omg_shared_ca_permissions.xsd\">\n"" <permissions>\n");/* 2. 生成Grant */result = GenerateGrantXml(mapping,"ServiceInstanceGrant",xmlBuffer + written,sizeof(xmlBuffer) - written);if (result != E_OK) {return E_NOT_OK;}written = strlen(xmlBuffer);/* 3. 根据服务实例类型生成权限 */if (serviceInstance->type == SERVICE_INSTANCE_PROVIDED) {const DdsProvidedServiceInstance_Type* provided =(const DdsProvidedServiceInstance_Type*)serviceInstance;/* 生成发布权限 */result = GeneratePublishPermissions(provided,xmlBuffer + written,sizeof(xmlBuffer) - written);if (result != E_OK) {return E_NOT_OK;}written = strlen(xmlBuffer);/* 生成订阅权限 */result = GenerateSubscribePermissionsForProvided(provided,xmlBuffer + written,sizeof(xmlBuffer) - written);if (result != E_OK) {return E_NOT_OK;}written = strlen(xmlBuffer);} else if (serviceInstance->type == SERVICE_INSTANCE_REQUIRED) {const DdsRequiredServiceInstance_Type* required =(const DdsRequiredServiceInstance_Type*)serviceInstance;/* 生成发布权限 */result = GeneratePublishPermissionsForRequired(required,xmlBuffer + written,sizeof(xmlBuffer) - written);if (result != E_OK) {return E_NOT_OK;}written = strlen(xmlBuffer);/* 生成订阅权限 */result = GenerateSubscribePermissionsForRequired(required,xmlBuffer + written,sizeof(xmlBuffer) - written);if (result != E_OK) {return E_NOT_OK;}written = strlen(xmlBuffer);}/* 4. 结束allow_rule和grant */written += snprintf(xmlBuffer + written, sizeof(xmlBuffer) - written," </allow_rule>\n"" <default>DENY</default>\n"" </grant>\n"" </permissions>\n""</dds>\n");/* 5. 写入文件 */result = FileSystem_WriteFile(outputPath, (uint8*)xmlBuffer, written);return result;
}
7. 运行时配置和通信序列
7.1 初始化序列
DDS Security的运行时初始化序列展示了从应用启动到建立安全通信的完整过程。
7.1.1 应用启动阶段
步骤1: 初始化ara::com运行时
应用程序首先初始化ara::com运行时环境。
代码示例: ara::com初始化
/* ara::com运行时初始化 */
Std_ReturnType AraComRuntime_Initialize(void)
{Std_ReturnType result;/* 1. 初始化通信管理 */result = CommunicationManagement_Init();if (result != E_OK) {return E_NOT_OK;}/* 2. 初始化服务发现 */result = ServiceDiscovery_Init();if (result != E_OK) {CommunicationManagement_Deinit();return E_NOT_OK;}/* 3. 初始化DDS Network Binding */result = DdsNetworkBinding_Init();if (result != E_OK) {ServiceDiscovery_Deinit();CommunicationManagement_Deinit();return E_NOT_OK;}return E_OK;
}
步骤2: 加载Manifest配置
运行时加载应用的Manifest配置,包括服务实例映射和安全配置。
代码示例: Manifest配置加载
/* 加载Manifest配置 */
Std_ReturnType LoadManifestConfiguration(const char* manifestPath,ManifestConfig_Type* config)
{Std_ReturnType result;/* 1. 解析Manifest文件 */result = Manifest_Parse(manifestPath, config);if (result != E_OK) {return E_NOT_OK;}/* 2. 验证配置完整性 */result = Manifest_Validate(config);if (result != E_OK) {return E_NOT_OK;}/* 3. 加载服务实例映射 */for (uint8 i = 0; i < config->numServiceMappings; i++) {const DdsServiceInstanceToMachineMapping_Type* mapping =&config->serviceMappings[i];/* 注册服务实例映射 */result = RegisterServiceInstanceMapping(mapping);if (result != E_OK) {return E_NOT_OK;}}return E_OK;
}
7.1.2 Domain Participant创建阶段
步骤3: 加载QoS Profile
对于每个配置了DDS Security的服务实例,加载其QoS Profile。
代码示例: QoS Profile加载
/* 加载QoS Profile */
Std_ReturnType LoadQosProfile(const char* profileName,DomainParticipantQos_SecurityProperties* secProps)
{Std_ReturnType result;char qosLibraryPath[256];/* 1. 构造QoS Library路径 */snprintf(qosLibraryPath, sizeof(qosLibraryPath),"file:///etc/dds/config/qos_profiles.xml");/* 2. 加载XML文件 */result = QosProfile_LoadLibrary(qosLibraryPath);if (result != E_OK) {return E_NOT_OK;}/* 3. 提取安全属性 */result = LoadSecurityConfiguration(profileName, secProps);if (result != E_OK) {return E_NOT_OK;}/* 4. 验证路径有效性 */result = ValidateSecurityArtifactPaths(secProps);if (result != E_OK) {return E_NOT_OK;}return E_OK;
}/* 验证安全制品路径 */
Std_ReturnType ValidateSecurityArtifactPaths(const DomainParticipantQos_SecurityProperties* secProps)
{/* 检查身份证书 */if (!FileSystem_FileExists(secProps->identity_certificate)) {return E_NOT_OK;}/* 检查身份CA */if (!FileSystem_FileExists(secProps->identity_ca)) {return E_NOT_OK;}/* 检查私钥 */if (!FileSystem_FileExists(secProps->private_key)) {return E_NOT_OK;}/* 检查权限CA */if (!FileSystem_FileExists(secProps->permissions_ca)) {return E_NOT_OK;}/* 检查治理文档 */if (!FileSystem_FileExists(secProps->governance)) {return E_NOT_OK;}/* 检查权限文档 */if (!FileSystem_FileExists(secProps->permissions)) {return E_NOT_OK;}return E_OK;
}
步骤4: 验证安全制品
加载后验证所有安全制品的签名和有效性。
代码示例: 安全制品验证
/* 验证所有安全制品 */
Std_ReturnType VerifySecurityArtifacts(const DomainParticipantQos_SecurityProperties* secProps,const DdsSecureComProps_ConfigType* secureComProps)
{Std_ReturnType result;/* 1. 验证身份证书 */result = VerifyIdentityCertificate(secProps->identity_certificate,secProps->identity_ca);if (result != E_OK) {return E_NOT_OK;}/* 2. 验证治理文档签名 */result = VerifyGovernanceDocument(secProps->governance,secureComProps->governance->permissionCertificateAuthority);if (result != E_OK) {return E_NOT_OK;}/* 3. 验证权限文档签名 */result = VerifyPermissionsDocument(secProps->permissions,secureComProps->governance->permissionCertificateAuthority);if (result != E_OK) {return E_NOT_OK;}/* 4. 验证权限文档有效期 */result = VerifyPermissionsValidity(secProps->permissions);if (result != E_OK) {return E_NOT_OK;}return E_OK;
}/* 验证身份证书 */
Std_ReturnType VerifyIdentityCertificate(const char* identityCertPath,const char* identityCAPath)
{uint8 certBuffer[MAX_CERT_SIZE];uint32 certLength;uint8 caBuffer[MAX_CERT_SIZE];uint32 caLength;Std_ReturnType result;/* 加载身份证书 */result = FileSystem_ReadFile(identityCertPath, certBuffer, &certLength);if (result != E_OK) {return E_NOT_OK;}/* 加载CA证书 */result = FileSystem_ReadFile(identityCAPath, caBuffer, &caLength);if (result != E_OK) {return E_NOT_OK;}/* 验证证书链 */result = X509_VerifyCertificateChain(certBuffer,certLength,caBuffer,caLength);if (result != E_OK) {return E_NOT_OK;}/* 验证证书有效期 */result = X509_VerifyValidity(certBuffer, certLength);return result;
}/* 验证权限文档有效期 */
Std_ReturnType VerifyPermissionsValidity(const char* permissionsPath)
{uint8 docBuffer[MAX_DOCUMENT_SIZE];uint32 docLength;Std_ReturnType result;time_t currentTime;time_t notBefore;time_t notAfter;/* 读取权限文档 */result = FileSystem_ReadFile(permissionsPath, docBuffer, &docLength);if (result != E_OK) {return E_NOT_OK;}/* 解析validity元素 */result = Permissions_ParseValidity(docBuffer,docLength,¬Before,¬After);if (result != E_OK) {return E_NOT_OK;}/* 获取当前时间 */currentTime = time(NULL);/* 检查有效期 */if (currentTime < notBefore || currentTime > notAfter) {return E_NOT_OK; /* 不在有效期内 */}return E_OK;
}
步骤5: 创建安全Domain Participant
验证通过后,创建启用DDS Security的Domain Participant。
代码示例: 安全Domain Participant创建
/* 创建安全Domain Participant的完整流程 */
Std_ReturnType CreateSecureDomainParticipantWithValidation(const DdsServiceInstanceToMachineMapping_Type* mapping,DDS_DomainParticipant** participant)
{DomainParticipantQos_SecurityProperties secProps;const char* qosProfileName;Std_ReturnType result;DDS_DomainId_t domainId;/* 1. 获取QoS Profile名称 */if (mapping->serviceInstance->type == SERVICE_INSTANCE_PROVIDED) {qosProfileName = ((DdsProvidedServiceInstance_Type*)mapping->serviceInstance)->qosProfile;} else {qosProfileName = ((DdsRequiredServiceInstance_Type*)mapping->serviceInstance)->qosProfile;}/* 2. 加载QoS Profile */result = LoadQosProfile(qosProfileName, &secProps);if (result != E_OK) {return E_NOT_OK;}/* 3. 验证安全制品 */result = VerifySecurityArtifacts(&secProps,mapping->secureComPropsForDds);if (result != E_OK) {return E_NOT_OK;}/* 4. 获取域ID */domainId = mapping->secureComPropsForDds->governance->domainId[0];/* 5. 创建Domain Participant */*participant = CreateSecureDomainParticipant(domainId, &secProps);if (*participant == NULL) {return E_NOT_OK;}/* 6. 等待Authentication完成 */result = WaitForAuthentication(*participant, AUTHENTICATION_TIMEOUT_MS);if (result != E_OK) {DDS_DomainParticipant_delete(*participant);*participant = NULL;return E_NOT_OK;}return E_OK;
}/* 等待Authentication完成 */
Std_ReturnType WaitForAuthentication(DDS_DomainParticipant* participant,uint32 timeoutMs)
{uint32 elapsedMs = 0;DDS_ParticipantBuiltinTopicData participantData;DDS_ReturnCode_t rc;/* 轮询检查Participant状态 */while (elapsedMs < timeoutMs) {/* 获取Participant内置数据 */rc = DDS_DomainParticipant_get_discovered_participants(participant,&participantData);if (rc == DDS_RETCODE_OK) {/* Authentication完成 */return E_OK;}/* 等待100ms */OsDelay(100);elapsedMs += 100;}/* 超时 */return E_NOT_OK;
}
7.2 发现序列
7.2.1 Service Discovery阶段
步骤6-7: Service Discovery
Service Discovery机制在DDS层面通过Discovery Protocol实现。
代码示例: Service Discovery实现
/* Service Discovery - FindService实现 */
Std_ReturnType AraComServiceDiscovery_FindService(const char* serviceInstanceId,ServiceHandleContainer_Type* handleContainer)
{Std_ReturnType result;DDS_DomainParticipant* participant;DDS_DataReader* discoveryReader;DDS_SampleInfoSeq infoSeq;DDS_ParticipantBuiltinTopicDataSeq dataSeq;DDS_ReturnCode_t rc;/* 1. 获取本地Domain Participant */participant = GetLocalDomainParticipant();if (participant == NULL) {return E_NOT_OK;}/* 2. 获取Discovery DataReader */discoveryReader = DDS_DomainParticipant_get_builtin_subscriber(participant);if (discoveryReader == NULL) {return E_NOT_OK;}/* 3. 读取Discovery数据 */rc = DDS_DataReader_read(discoveryReader,&dataSeq,&infoSeq,DDS_LENGTH_UNLIMITED,DDS_ANY_SAMPLE_STATE,DDS_ANY_VIEW_STATE,DDS_ANY_INSTANCE_STATE);if (rc != DDS_RETCODE_OK) {return E_NOT_OK;}/* 4. 过滤匹配的服务实例 */for (DDS_Long i = 0; i < DDS_ParticipantBuiltinTopicDataSeq_get_length(&dataSeq); i++) {DDS_ParticipantBuiltinTopicData* data =DDS_ParticipantBuiltinTopicDataSeq_get_reference(&dataSeq, i);/* 检查是否匹配请求的服务实例 */if (IsServiceInstanceMatch(data, serviceInstanceId)) {/* 创建Service Handle */ServiceHandle_Type* handle = CreateServiceHandle(data);if (handle != NULL) {AddServiceHandle(handleContainer, handle);}}}/* 5. 释放资源 */DDS_DataReader_return_loan(discoveryReader, &dataSeq, &infoSeq);return E_OK;
}/* 检查服务实例匹配 */
boolean IsServiceInstanceMatch(const DDS_ParticipantBuiltinTopicData* data,const char* serviceInstanceId)
{/* 从user_data中提取服务实例信息 */const char* instanceId = ExtractServiceInstanceId(data->user_data);if (instanceId == NULL) {return FALSE;}/* 比较服务实例ID */return (strcmp(instanceId, serviceInstanceId) == 0);
}
7.2.2 Authentication和Access Control
步骤8-9: Authentication握手
当发现远程Participant时,DDS Security Plugins执行Authentication握手。
代码示例: Authentication握手流程
/* Authentication Plugin - 完整握手流程 */
Std_ReturnType AuthenticationPlugin_PerformHandshake(DDS_Security_IdentityHandle local_identity,DDS_Security_IdentityHandle remote_identity,DDS_Security_SharedSecretHandle* shared_secret)
{DDS_Security_AuthRequestMessageToken local_token;DDS_Security_AuthRequestMessageToken remote_token;DDS_Security_AuthRequestMessageToken handshake_reply;DDS_Security_SecurityException ex;DDS_Security_boolean result;/* 1. 验证远程身份 */result = AuthenticationPlugin_ValidateRemoteIdentity(&remote_identity,&local_token,&remote_token,local_identity,/* remote_identity_token */ NULL,/* remote_participant_guid */ NULL,&ex);if (!result) {return E_NOT_OK;}/* 2. 开始握手 */result = AuthenticationPlugin_BeginHandshakeRequest(&handshake_reply,&local_token,local_identity,remote_identity,/* handshake_message */ NULL,&ex);if (!result) {return E_NOT_OK;}/* 3. 处理握手回复 */result = AuthenticationPlugin_ProcessHandshakeReply(&handshake_reply,&local_token,local_identity,remote_identity,/* handshake_message */ NULL,&ex);if (!result) {return E_NOT_OK;}/* 4. 完成握手,获取共享密钥 */result = AuthenticationPlugin_GetSharedSecret(shared_secret,local_identity,remote_identity,&ex);if (!result) {return E_NOT_OK;}return E_OK;
}
步骤10-11: Access Control检查
Authentication成功后,Access Control Plugin检查权限。
代码示例: Access Control检查
/* Access Control Plugin - 完整权限检查 */
Std_ReturnType AccessControlPlugin_ValidateRemoteParticipant(DDS_Security_PermissionsHandle local_permissions,DDS_Security_IdentityHandle remote_identity,DDS_Security_PermissionsHandle* remote_permissions)
{DDS_Security_PermissionsToken remote_permissions_token;DDS_Security_SecurityException ex;DDS_Security_boolean result;/* 1. 验证远程权限令牌 */result = AccessControlPlugin_ValidateRemotePermissions(remote_permissions,local_permissions,/* domain_id */ 0,remote_identity,&remote_permissions_token,&ex);if (!result) {return E_NOT_OK;}/* 2. 检查域访问权限 */result = AccessControlPlugin_CheckRemoteParticipant(local_permissions,/* domain_id */ 0,remote_identity,&ex);if (!result) {return E_NOT_OK;}/* 3. 检查主题发现权限 */result = AccessControlPlugin_CheckRemoteDatareader(local_permissions,/* domain_id */ 0,remote_identity,/* topic_name */ "ara.com://services/discovery",&ex);if (!result) {return E_NOT_OK;}return E_OK;
}
7.3 通信序列
7.3.1 安全通信建立
步骤12-13: 创建DataWriter/DataReader
权限验证通过后,创建DataWriter和DataReader用于实际通信。
代码示例: 安全DataWriter创建
/* 创建启用安全的DataWriter */
DDS_DataWriter* CreateSecureDataWriter(DDS_DomainParticipant* participant,const char* topicName,const DdsEventQosProps_Type* qosProps)
{DDS_Publisher* publisher;DDS_Topic* topic;DDS_DataWriter* writer;DDS_DataWriterQos writerQos;DDS_ReturnCode_t rc;/* 1. 获取Publisher */publisher = DDS_DomainParticipant_get_implicit_publisher(participant);if (publisher == NULL) {return NULL;}/* 2. 创建或查找Topic */topic = DDS_DomainParticipant_find_topic(participant,topicName,&DDS_DURATION_ZERO);if (topic == NULL) {/* 创建新Topic */topic = DDS_DomainParticipant_create_topic(participant,topicName,/* type_name */ "EventData",&DDS_TOPIC_QOS_DEFAULT,NULL, /* listener */DDS_STATUS_MASK_NONE);}if (topic == NULL) {return NULL;}/* 3. 配置DataWriter QoS */rc = DDS_Publisher_get_default_datawriter_qos(publisher, &writerQos);if (rc != DDS_RETCODE_OK) {return NULL;}/* 应用服务特定的QoS设置 */ApplyEventQosToDataWriter(&writerQos, qosProps);/* 4. 创建DataWriter */writer = DDS_Publisher_create_datawriter(publisher,topic,&writerQos,NULL, /* listener */DDS_STATUS_MASK_NONE);/* 5. 释放QoS资源 */DDS_DataWriterQos_finalize(&writerQos);return writer;
}/* 应用Event QoS设置 */
void ApplyEventQosToDataWriter(DDS_DataWriterQos* writerQos,const DdsEventQosProps_Type* qosProps)
{/* Reliability */if (qosProps->reliability == DDS_RELIABLE_RELIABILITY_QOS) {writerQos->reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;} else {writerQos->reliability.kind = DDS_BEST_EFFORT_RELIABILITY_QOS;}/* Durability */writerQos->durability.kind = qosProps->durability;/* History */writerQos->history.kind = DDS_KEEP_LAST_HISTORY_QOS;writerQos->history.depth = qosProps->historyDepth;/* Deadline */if (qosProps->hasDeadline) {writerQos->deadline.period.sec = qosProps->deadlineSec;writerQos->deadline.period.nanosec = qosProps->deadlineNanosec;}
}
代码示例: 安全DataReader创建
/* 创建启用安全的DataReader */
DDS_DataReader* CreateSecureDataReader(DDS_DomainParticipant* participant,const char* topicName,const DdsEventQosProps_Type* qosProps,DDS_DataReaderListener* listener)
{DDS_Subscriber* subscriber;DDS_Topic* topic;DDS_DataReader* reader;DDS_DataReaderQos readerQos;DDS_ReturnCode_t rc;/* 1. 获取Subscriber */subscriber = DDS_DomainParticipant_get_implicit_subscriber(participant);if (subscriber == NULL) {return NULL;}/* 2. 创建或查找Topic */topic = DDS_DomainParticipant_find_topic(participant,topicName,&DDS_DURATION_ZERO);if (topic == NULL) {topic = DDS_DomainParticipant_create_topic(participant,topicName,"EventData",&DDS_TOPIC_QOS_DEFAULT,NULL,DDS_STATUS_MASK_NONE);}if (topic == NULL) {return NULL;}/* 3. 配置DataReader QoS */rc = DDS_Subscriber_get_default_datareader_qos(subscriber, &readerQos);if (rc != DDS_RETCODE_OK) {return NULL;}/* 应用服务特定的QoS设置 */ApplyEventQosToDataReader(&readerQos, qosProps);/* 4. 创建DataReader */reader = DDS_Subscriber_create_datareader(subscriber,topic,&readerQos,listener,DDS_DATA_AVAILABLE_STATUS);/* 5. 释放QoS资源 */DDS_DataReaderQos_finalize(&readerQos);return reader;
}/* 应用Event QoS设置到DataReader */
void ApplyEventQosToDataReader(DDS_DataReaderQos* readerQos,const DdsEventQosProps_Type* qosProps)
{/* Reliability */if (qosProps->reliability == DDS_RELIABLE_RELIABILITY_QOS) {readerQos->reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;} else {readerQos->reliability.kind = DDS_BEST_EFFORT_RELIABILITY_QOS;}/* Durability */readerQos->durability.kind = qosProps->durability;/* History */readerQos->history.kind = DDS_KEEP_LAST_HISTORY_QOS;readerQos->history.depth = qosProps->historyDepth;/* Deadline */if (qosProps->hasDeadline) {readerQos->deadline.period.sec = qosProps->deadlineSec;readerQos->deadline.period.nanosec = qosProps->deadlineNanosec;}
}
7.3.2 加密通信
步骤14-17: 数据加密和传输
实际数据传输时,Cryptographic Plugin自动进行加密和签名。
代码示例: 加密数据发送
/* 发送加密数据 */
Std_ReturnType SendEncryptedEvent(DDS_DataWriter* writer,const void* eventData,uint32 eventDataSize)
{DDS_ReturnCode_t rc;/* DataWriter会自动调用Cryptographic Plugin进行加密 *//* 根据Governance Document中的data_protection_kind设置 *//* 1. 写入数据 */rc = DDS_DataWriter_write(writer,eventData,&DDS_HANDLE_NIL);if (rc != DDS_RETCODE_OK) {return E_NOT_OK;}/* 数据在DDS层自动加密和签名 *//* Cryptographic Plugin处理流程: *//* a. 获取数据保护类型 *//* b. 如果需要加密,使用共享密钥加密数据 *//* c. 如果需要签名,使用私钥签名 *//* d. 将加密/签名的数据发送到网络 */return E_OK;
}
代码示例: 解密数据接收
/* DataReader Listener回调 */
void EventDataReaderListener_OnDataAvailable(void* listener_data,DDS_DataReader* reader)
{DDS_SampleInfoSeq infoSeq;EventDataSeq dataSeq;DDS_ReturnCode_t rc;/* 1. 读取数据 *//* DataReader会自动调用Cryptographic Plugin进行解密和验证 */rc = DDS_DataReader_take(reader,&dataSeq,&infoSeq,DDS_LENGTH_UNLIMITED,DDS_ANY_SAMPLE_STATE,DDS_ANY_VIEW_STATE,DDS_ANY_INSTANCE_STATE);if (rc != DDS_RETCODE_OK) {return;}/* Cryptographic Plugin处理流程: *//* a. 接收加密/签名的数据 *//* b. 如果有签名,使用远程Participant的公钥验证 *//* c. 如果加密,使用共享密钥解密 *//* d. 返回明文数据 *//* 2. 处理接收的数据 */for (DDS_Long i = 0; i < EventDataSeq_get_length(&dataSeq); i++) {DDS_SampleInfo* info = DDS_SampleInfoSeq_get_reference(&infoSeq, i);if (info->valid_data) {EventData* data = EventDataSeq_get_reference(&dataSeq, i);/* 调用应用层回调 */ProcessEventData(data);}}/* 3. 归还loan */DDS_DataReader_return_loan(reader, &dataSeq, &infoSeq);
}/* 应用层事件数据处理 */
void ProcessEventData(const EventData* data)
{/* 应用程序处理解密后的数据 *//* 应用层无需关心加密/解密细节 *//* 示例: 处理雷达对象数据 */if (data->eventType == EVENT_TYPE_RADAR_OBJECTS) {RadarObjects* objects = (RadarObjects*)data->payload;for (uint16 i = 0; i < objects->numObjects; i++) {/* 处理每个雷达对象 */ProcessRadarObject(&objects->objects[i]);}}
}
7.3.3 完整通信示例
代码示例: 端到端安全通信示例
/* Provider端:提供服务的完整流程 */
Std_ReturnType ProviderSide_SecureCommunication(void)
{DDS_DomainParticipant* participant;DDS_DataWriter* eventWriter;Std_ReturnType result;const DdsServiceInstanceToMachineMapping_Type* mapping;/* 1. 获取服务实例映射 */mapping = GetProvidedServiceMapping("RadarService/1");if (mapping == NULL) {return E_NOT_OK;}/* 2. 创建安全Domain Participant */result = CreateSecureDomainParticipantWithValidation(mapping,&participant);if (result != E_OK) {return E_NOT_OK;}/* 3. 创建Event DataWriter */eventWriter = CreateSecureDataWriter(participant,"ara.com://services/RadarService/1.0/RadarObjects",/* qosProps */ &RadarObjectsEventQos);if (eventWriter == NULL) {DDS_DomainParticipant_delete(participant);return E_NOT_OK;}/* 4. 周期性发送事件数据 */while (isRunning) {RadarObjects radarObjects;/* 获取雷达数据 */GetRadarObjects(&radarObjects);/* 发送加密事件 (自动加密) */result = SendEncryptedEvent(eventWriter,&radarObjects,sizeof(radarObjects));if (result != E_OK) {/* 处理发送错误 */}/* 等待下一个周期 */OsDelay(100); /* 100ms */}/* 5. 清理 */DDS_DataWriter_delete(eventWriter);DDS_DomainParticipant_delete(participant);return E_OK;
}/* Consumer端:使用服务的完整流程 */
Std_ReturnType ConsumerSide_SecureCommunication(void)
{DDS_DomainParticipant* participant;DDS_DataReader* eventReader;DDS_DataReaderListener listener;Std_ReturnType result;const DdsServiceInstanceToMachineMapping_Type* mapping;/* 1. 获取服务实例映射 */mapping = GetRequiredServiceMapping("RadarService/1");if (mapping == NULL) {return E_NOT_OK;}/* 2. 创建安全Domain Participant */result = CreateSecureDomainParticipantWithValidation(mapping,&participant);if (result != E_OK) {return E_NOT_OK;}/* 3. 配置DataReader Listener */memset(&listener, 0, sizeof(listener));listener.on_data_available = EventDataReaderListener_OnDataAvailable;/* 4. 创建Event DataReader */eventReader = CreateSecureDataReader(participant,"ara.com://services/RadarService/*/RadarObjects",/* qosProps */ &RadarObjectsEventQos,&listener);if (eventReader == NULL) {DDS_DomainParticipant_delete(participant);return E_NOT_OK;}/* 5. 主循环 (数据通过回调接收) */while (isRunning) {/* 处理其他任务 */OsDelay(100);}/* 6. 清理 */DDS_DataReader_delete(eventReader);DDS_DomainParticipant_delete(participant);return E_OK;
}
8. 代码实现示例
8.1 配置数据结构
8.1.1 完整的配置数据结构定义
本节提供完整的C语言配置数据结构定义,用于实现AUTOSAR DDS Security集成。
代码示例: 核心数据结构定义
/* ========== 核心数据类型定义 ========== *//* Boolean类型 */
typedef uint8 boolean;
#define TRUE 1
#define FALSE 0/* 标准返回类型 */
typedef enum {E_OK = 0,E_NOT_OK = 1
} Std_ReturnType;/* ========== DDS保护类型 ========== */typedef enum {DDS_PROTECTION_KIND_NONE = 0,DDS_PROTECTION_KIND_SIGN = 1,DDS_PROTECTION_KIND_ENCRYPT = 2,DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION = 3
} DdsProtectionKindEnum;/* ========== 加密配置 ========== *//* 加密对象类型 */
typedef enum {CRYPTO_OBJECT_TYPE_SYMMETRIC_KEY = 0,CRYPTO_OBJECT_TYPE_PRIVATE_KEY = 1,CRYPTO_OBJECT_TYPE_PUBLIC_KEY = 2,CRYPTO_OBJECT_TYPE_CERTIFICATE = 3
} CryptoObjectTypeEnum;/* 密钥槽位类型 */
typedef enum {CRYPTO_KEY_SLOT_TYPE_APPLICATION = 0,CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE = 1
} CryptoKeySlotTypeEnum;/* 加密证书 */
typedef struct {const char* shortName;boolean isPrivate;const char* certPath;
} CryptoCertificate_Type;/* 密钥槽位 */
typedef struct {const char* shortName;const char* cryptoAlgId;CryptoObjectTypeEnum cryptoObjectType;uint32 slotCapacity;CryptoKeySlotTypeEnum slotType;boolean allocateShadow;
} CryptoKeySlot_Type;/* 证书到密钥槽位映射 */
#define MAX_KEY_SLOTS 2
typedef struct {const CryptoCertificate_Type* cryptoCertificate;const CryptoKeySlot_Type* cryptoKeySlot[MAX_KEY_SLOTS];uint8 numKeySlots;
} CryptoCertificateToCryptoKeySlotMapping_Type;/* ========== DDS Security治理配置 ========== */#define MAX_DOMAINS 16
typedef struct {uint32 domainId[MAX_DOMAINS];uint8 numDomains;boolean allowUnauthenticatedParticipants;boolean enableJoinAccessControl;DdsProtectionKindEnum discoveryProtectionKind;DdsProtectionKindEnum livelinessProtectionKind;DdsProtectionKindEnum rtpsProtectionKind;const CryptoCertificate_Type* identityCertificateAuthority;const CryptoCertificate_Type* permissionCertificateAuthority;
} DdsSecureGovernance_Type;/* DDS安全通信属性 */
typedef struct {const CryptoCertificate_Type* identity;const DdsSecureGovernance_Type* governance;
} DdsSecureComProps_ConfigType;/* ========== DDS Service配置 ========== *//* DDS Topic访问规则 */
typedef struct {boolean enableDiscoveryProtection;boolean enableLivelinessProtection;boolean enableReadAccessControl;boolean enableWriteAccessControl;DdsProtectionKindEnum metadataProtectionKind;DdsProtectionKindEnum dataProtectionKind;
} DdsTopicAccessRule_Type;/* DDS Event部署 */
typedef struct {const char* topicName;const DdsTopicAccessRule_Type* eventTopicAccessRule;
} DdsEventDeployment_Type;/* DDS Service Interface部署 */
#define MAX_EVENTS 32
typedef struct {const char* serviceInterfaceId;const char* methodRequestTopicName;const char* methodReplyTopicName;const DdsTopicAccessRule_Type* methodTopicsAccessRule;const char* fieldRequestTopicName;const char* fieldReplyTopicName;const DdsTopicAccessRule_Type* fieldTopicsAccessRule;const DdsEventDeployment_Type* eventDeployment[MAX_EVENTS];uint8 numEvents;
} DdsServiceInterfaceDeployment_Type;/* DDS Event QoS属性 */
typedef struct {uint8 reliability; /* DDS_RELIABLE_RELIABILITY_QOS or DDS_BEST_EFFORT_RELIABILITY_QOS */uint8 durability; /* DDS_VOLATILE_DURABILITY_QOS, etc. */uint32 historyDepth;boolean hasDeadline;uint32 deadlineSec;uint32 deadlineNanosec;
} DdsEventQosProps_Type;/* DDS Field QoS属性 */
typedef struct {const char* topicName;uint8 reliability;uint8 durability;uint32 historyDepth;
} DdsFieldQosProps_Type;/* DDS Provided Service Instance */
#define MAX_FIELDS 16
typedef struct {uint16 serviceInstanceId;const char* qosProfile;const DdsServiceInterfaceDeployment_Type* serviceInterfaceDeployment;const DdsEventQosProps_Type* eventQosProps[MAX_EVENTS];uint8 numEventQosProps;const DdsFieldQosProps_Type* fieldNotifierQosProps[MAX_FIELDS];uint8 numFieldNotifierQosProps;
} DdsProvidedServiceInstance_Type;/* DDS Required Service Instance */
typedef struct {uint16 serviceInstanceId;const char* qosProfile;const DdsServiceInterfaceDeployment_Type* serviceInterfaceDeployment;
} DdsRequiredServiceInstance_Type;/* 服务实例类型标识 */
typedef enum {SERVICE_INSTANCE_PROVIDED = 0,SERVICE_INSTANCE_REQUIRED = 1
} ServiceInstanceTypeEnum;/* 通用服务实例 */
typedef struct {ServiceInstanceTypeEnum type;union {const DdsProvidedServiceInstance_Type* provided;const DdsRequiredServiceInstance_Type* required;} instance;
} DdsServiceInstance_Type;/* 通信连接器 */
typedef struct {const char* connectorName;const char* networkInterface;uint16 port;
} CommunicationConnector_Type;/* DDS服务实例到机器的映射 */
typedef struct {const DdsServiceInstance_Type* serviceInstance;const CommunicationConnector_Type* communicationConnector;const DdsSecureComProps_ConfigType* secureComPropsForDds;
} DdsServiceInstanceToMachineMapping_Type;
8.1.2 配置实例化示例
代码示例: 完整的配置实例
/* ========== CA证书配置 ========== */static const CryptoCertificate_Type IdentityCA = {.shortName = "IdentityCA",.isPrivate = FALSE,.certPath = "file:///etc/dds/certs/identity_ca.pem"
};static const CryptoCertificate_Type PermissionsCA = {.shortName = "PermissionsCA",.isPrivate = FALSE,.certPath = "file:///etc/dds/certs/permissions_ca.pem"
};/* ========== Participant身份证书配置 ========== */static const CryptoCertificate_Type RadarServiceIdentityCert = {.shortName = "RadarServiceIdentity",.isPrivate = TRUE,.certPath = "file:///etc/dds/certs/radar_service_identity.pem"
};/* ========== 密钥槽位配置 ========== */static const CryptoKeySlot_Type IdentityPrivateKeySlot = {.shortName = "IdentityPrivateKey",.cryptoAlgId = "RSA-2048",.cryptoObjectType = CRYPTO_OBJECT_TYPE_PRIVATE_KEY,.slotCapacity = 256,.slotType = CRYPTO_KEY_SLOT_TYPE_STACK_SERVICE,.allocateShadow = TRUE
};/* ========== 证书到密钥槽位映射 ========== */static const CryptoCertificateToCryptoKeySlotMapping_Type RadarIdentityCertMapping = {.cryptoCertificate = &RadarServiceIdentityCert,.cryptoKeySlot = {&IdentityPrivateKeySlot, NULL},.numKeySlots = 1
};/* ========== DDS治理配置 ========== */static const DdsSecureGovernance_Type AutomotiveSecureGovernance = {.domainId = {0},.numDomains = 1,.allowUnauthenticatedParticipants = FALSE,.enableJoinAccessControl = TRUE,.discoveryProtectionKind = DDS_PROTECTION_KIND_SIGN,.livelinessProtectionKind = DDS_PROTECTION_KIND_SIGN,.rtpsProtectionKind = DDS_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION,.identityCertificateAuthority = &IdentityCA,.permissionCertificateAuthority = &PermissionsCA
};/* ========== DDS安全通信属性 ========== */static const DdsSecureComProps_ConfigType RadarServiceSecureComProps = {.identity = &RadarServiceIdentityCert,.governance = &AutomotiveSecureGovernance
};/* ========== Topic访问规则 ========== */static const DdsTopicAccessRule_Type RadarEventsAccessRule = {.enableDiscoveryProtection = TRUE,.enableLivelinessProtection = FALSE,.enableReadAccessControl = TRUE,.enableWriteAccessControl = TRUE,.metadataProtectionKind = DDS_PROTECTION_KIND_NONE,.dataProtectionKind = DDS_PROTECTION_KIND_ENCRYPT
};static const DdsTopicAccessRule_Type RadarMethodsAccessRule = {.enableDiscoveryProtection = TRUE,.enableLivelinessProtection = FALSE,.enableReadAccessControl = TRUE,.enableWriteAccessControl = TRUE,.metadataProtectionKind = DDS_PROTECTION_KIND_SIGN,.dataProtectionKind = DDS_PROTECTION_KIND_ENCRYPT
};/* ========== Event部署 ========== */static const DdsEventDeployment_Type RadarObjectsEventDeployment = {.topicName = "RadarObjects",.eventTopicAccessRule = &RadarEventsAccessRule
};static const DdsEventDeployment_Type RadarStatusEventDeployment = {.topicName = "RadarStatus",.eventTopicAccessRule = &RadarEventsAccessRule
};/* ========== Service Interface部署 ========== */static const DdsServiceInterfaceDeployment_Type RadarServiceInterfaceDeployment = {.serviceInterfaceId = "RadarService",.methodRequestTopicName = "RadarMethods_Req",.methodReplyTopicName = "RadarMethods_Rep",.methodTopicsAccessRule = &RadarMethodsAccessRule,.fieldRequestTopicName = "RadarFields_Req",.fieldReplyTopicName = "RadarFields_Rep",.fieldTopicsAccessRule = &RadarMethodsAccessRule,.eventDeployment = {&RadarObjectsEventDeployment,&RadarStatusEventDeployment,NULL},.numEvents = 2
};/* ========== Event QoS配置 ========== */static const DdsEventQosProps_Type RadarObjectsEventQos = {.reliability = DDS_RELIABLE_RELIABILITY_QOS,.durability = DDS_VOLATILE_DURABILITY_QOS,.historyDepth = 10,.hasDeadline = TRUE,.deadlineSec = 0,.deadlineNanosec = 100000000 /* 100ms */
};static const DdsEventQosProps_Type RadarStatusEventQos = {.reliability = DDS_BEST_EFFORT_RELIABILITY_QOS,.durability = DDS_VOLATILE_DURABILITY_QOS,.historyDepth = 1,.hasDeadline = FALSE,.deadlineSec = 0,.deadlineNanosec = 0
};/* ========== Provided Service Instance ========== */static const DdsProvidedServiceInstance_Type RadarProvidedServiceInstance = {.serviceInstanceId = 1,.qosProfile = "RadarServiceQoSProfile",.serviceInterfaceDeployment = &RadarServiceInterfaceDeployment,.eventQosProps = {&RadarObjectsEventQos,&RadarStatusEventQos,NULL},.numEventQosProps = 2,.fieldNotifierQosProps = {NULL},.numFieldNotifierQosProps = 0
};/* ========== 通信连接器 ========== */static const CommunicationConnector_Type EthernetConnector = {.connectorName = "EthConnector",.networkInterface = "eth0",.port = 7400
};/* ========== 服务实例映射 ========== */static const DdsServiceInstance_Type RadarServiceInstance = {.type = SERVICE_INSTANCE_PROVIDED,.instance.provided = &RadarProvidedServiceInstance
};static const DdsServiceInstanceToMachineMapping_Type RadarServiceMapping = {.serviceInstance = &RadarServiceInstance,.communicationConnector = &EthernetConnector,.secureComPropsForDds = &RadarServiceSecureComProps
};
8.2 运行时API调用
8.2.1 服务实例初始化
代码示例: 完整的服务实例初始化流程
/* 初始化所有配置的服务实例 */
Std_ReturnType InitializeAllServiceInstances(void)
{Std_ReturnType result;uint8 numMappings;const DdsServiceInstanceToMachineMapping_Type* mappings;/* 1. 获取所有服务实例映射 */mappings = GetServiceInstanceMappings(&numMappings);if (mappings == NULL || numMappings == 0) {return E_NOT_OK;}/* 2. 遍历并初始化每个映射 */for (uint8 i = 0; i < numMappings; i++) {const DdsServiceInstanceToMachineMapping_Type* mapping = &mappings[i];/* 检查是否需要安全通信 */if (mapping->secureComPropsForDds != NULL) {/* 初始化安全服务实例 */result = InitializeSecureServiceInstance(mapping);} else {/* 初始化非安全服务实例 */result = InitializeNonSecureServiceInstance(mapping);}if (result != E_OK) {/* 初始化失败,回滚已初始化的实例 */RollbackServiceInstances(i);return E_NOT_OK;}}return E_OK;
}/* 初始化安全服务实例 */
Std_ReturnType InitializeSecureServiceInstance(const DdsServiceInstanceToMachineMapping_Type* mapping)
{DDS_DomainParticipant* participant;Std_ReturnType result;/* 1. 创建安全Domain Participant */result = CreateSecureDomainParticipantWithValidation(mapping,&participant);if (result != E_OK) {return E_NOT_OK;}/* 2. 根据服务实例类型创建Endpoints */if (mapping->serviceInstance->type == SERVICE_INSTANCE_PROVIDED) {/* 创建Provided Service的Publishers和DataWriters */result = CreateProvidedServiceEndpoints(participant,mapping->serviceInstance->instance.provided);} else {/* 创建Required Service的Subscribers和DataReaders */result = CreateRequiredServiceEndpoints(participant,mapping->serviceInstance->instance.required);}if (result != E_OK) {DDS_DomainParticipant_delete(participant);return E_NOT_OK;}/* 3. 注册服务实例 */result = RegisterServiceInstance(mapping, participant);if (result != E_OK) {CleanupServiceEndpoints(participant);DDS_DomainParticipant_delete(participant);return E_NOT_OK;}return E_OK;
}/* 创建Provided Service的Endpoints */
Std_ReturnType CreateProvidedServiceEndpoints(DDS_DomainParticipant* participant,const DdsProvidedServiceInstance_Type* providedInstance)
{Std_ReturnType result;const DdsServiceInterfaceDeployment_Type* interfaceDeployment;interfaceDeployment = providedInstance->serviceInterfaceDeployment;/* 1. 为每个Event创建DataWriter */for (uint8 i = 0; i < providedInstance->numEventQosProps; i++) {const DdsEventDeployment_Type* eventDeployment =interfaceDeployment->eventDeployment[i];const DdsEventQosProps_Type* eventQos =providedInstance->eventQosProps[i];char topicName[256];snprintf(topicName, sizeof(topicName),"ara.com://services/%s/%u/%s",interfaceDeployment->serviceInterfaceId,providedInstance->serviceInstanceId,eventDeployment->topicName);DDS_DataWriter* writer = CreateSecureDataWriter(participant,topicName,eventQos);if (writer == NULL) {return E_NOT_OK;}/* 注册DataWriter */result = RegisterEventDataWriter(providedInstance->serviceInstanceId,i,writer);if (result != E_OK) {return E_NOT_OK;}}/* 2. 为方法Reply创建DataWriter */if (interfaceDeployment->methodReplyTopicName != NULL) {char topicName[256];snprintf(topicName, sizeof(topicName),"ara.com://services/%s/%u/%s",interfaceDeployment->serviceInterfaceId,providedInstance->serviceInstanceId,interfaceDeployment->methodReplyTopicName);DDS_DataWriter* writer = CreateSecureDataWriter(participant,topicName,/* qosProps */ &DefaultMethodQos);if (writer == NULL) {return E_NOT_OK;}result = RegisterMethodReplyWriter(providedInstance->serviceInstanceId,writer);if (result != E_OK) {return E_NOT_OK;}}/* 3. 为方法Request创建DataReader */if (interfaceDeployment->methodRequestTopicName != NULL) {char topicName[256];snprintf(topicName, sizeof(topicName),"ara.com://services/%s/*/%s",interfaceDeployment->serviceInterfaceId,interfaceDeployment->methodRequestTopicName);DDS_DataReaderListener listener;memset(&listener, 0, sizeof(listener));listener.on_data_available = MethodRequestListener_OnDataAvailable;DDS_DataReader* reader = CreateSecureDataReader(participant,topicName,/* qosProps */ &DefaultMethodQos,&listener);if (reader == NULL) {return E_NOT_OK;}result = RegisterMethodRequestReader(providedInstance->serviceInstanceId,reader);if (result != E_OK) {return E_NOT_OK;}}return E_OK;
}
8.2.2 事件发送和接收
代码示例: 事件发送实现
/* ara::com Event Proxy实现 */
typedef struct {uint16 serviceInstanceId;uint8 eventIndex;DDS_DataWriter* writer;
} EventProxy_Type;/* 发送事件 */
Std_ReturnType EventProxy_Send(EventProxy_Type* proxy,const void* eventData,uint32 eventDataSize)
{DDS_ReturnCode_t rc;if (proxy == NULL || proxy->writer == NULL) {return E_NOT_OK;}/* 写入DDS (自动加密) */rc = DDS_DataWriter_write(proxy->writer,eventData,&DDS_HANDLE_NIL);if (rc != DDS_RETCODE_OK) {return E_NOT_OK;}return E_OK;
}/* 应用层使用示例 */
void Application_SendRadarObjects(void)
{EventProxy_Type* radarObjectsEvent;RadarObjects objects;Std_ReturnType result;/* 获取Event Proxy */radarObjectsEvent = GetEventProxy(/* serviceInstanceId */ 1,/* eventIndex */ 0);if (radarObjectsEvent == NULL) {return;}/* 准备数据 */GetCurrentRadarObjects(&objects);/* 发送事件 */result = EventProxy_Send(radarObjectsEvent,&objects,sizeof(objects));if (result != E_OK) {/* 处理错误 */}
}
代码示例: 事件接收实现
/* ara::com Event Skeleton实现 */
typedef void (*EventReceiveCallback)(const void* eventData, uint32 dataSize);typedef struct {uint16 serviceInstanceId;uint8 eventIndex;DDS_DataReader* reader;EventReceiveCallback callback;
} EventSkeleton_Type;/* Event DataReader Listener */
void EventListener_OnDataAvailable(void* listener_data,DDS_DataReader* reader)
{EventSkeleton_Type* skeleton = (EventSkeleton_Type*)listener_data;DDS_SampleInfoSeq infoSeq;DDS_OctetSeq dataSeq;DDS_ReturnCode_t rc;/* 读取数据 (自动解密) */rc = DDS_DataReader_take(reader,&dataSeq,&infoSeq,DDS_LENGTH_UNLIMITED,DDS_ANY_SAMPLE_STATE,DDS_ANY_VIEW_STATE,DDS_ANY_INSTANCE_STATE);if (rc != DDS_RETCODE_OK) {return;}/* 处理每个样本 */for (DDS_Long i = 0; i < DDS_SampleInfoSeq_get_length(&infoSeq); i++) {DDS_SampleInfo* info = DDS_SampleInfoSeq_get_reference(&infoSeq, i);if (info->valid_data && skeleton->callback != NULL) {void* data = DDS_OctetSeq_get_reference(&dataSeq, i);uint32 dataSize = DDS_OctetSeq_get_length(&dataSeq);/* 调用应用层回调 */skeleton->callback(data, dataSize);}}/* 归还loan */DDS_DataReader_return_loan(reader, &dataSeq, &infoSeq);
}/* 应用层使用示例 */
void Application_ReceiveCallback(const void* eventData, uint32 dataSize)
{const RadarObjects* objects = (const RadarObjects*)eventData;/* 处理接收的雷达对象数据 */for (uint16 i = 0; i < objects->numObjects; i++) {ProcessRadarObject(&objects->objects[i]);}
}void Application_SubscribeRadarObjects(void)
{EventSkeleton_Type* radarObjectsEvent;/* 获取Event Skeleton */radarObjectsEvent = GetEventSkeleton(/* serviceInstanceId */ 1,/* eventIndex */ 0);if (radarObjectsEvent == NULL) {return;}/* 注册回调 */radarObjectsEvent->callback = Application_ReceiveCallback;
}
8.3 安全通信示例
8.3.1 端到端安全通信完整示例
代码示例: Provider应用程序
/* Provider应用程序 - main.c */#include "ara_com.h"
#include "radar_service.h"/* 全局变量 */
static boolean isRunning = TRUE;
static RadarServiceSkeleton_Type* radarSkeleton;/* 信号处理 */
void SignalHandler(int sig)
{if (sig == SIGINT || sig == SIGTERM) {isRunning = FALSE;}
}/* 雷达数据采集线程 */
void* RadarAcquisitionThread(void* arg)
{RadarObjects objects;Std_ReturnType result;while (isRunning) {/* 1. 从雷达硬件获取数据 */result = RadarHardware_GetObjects(&objects);if (result != E_OK) {OsDelay(10);continue;}/* 2. 发送事件 (自动加密) */result = RadarServiceSkeleton_SendRadarObjects(radarSkeleton,&objects);if (result != E_OK) {/* 记录错误 */LogError("Failed to send RadarObjects event");}/* 3. 等待下一个周期 (100ms) */OsDelay(100);}return NULL;
}/* 方法调用处理器 */
Std_ReturnType SetRadarModeHandler(RadarMode mode,SetRadarModeResult* result)
{/* 处理SetRadarMode方法调用 */Std_ReturnType ret = RadarHardware_SetMode(mode);if (ret == E_OK) {result->success = TRUE;result->errorCode = 0;} else {result->success = FALSE;result->errorCode = 1;}return ret;
}/* 主函数 */
int main(int argc, char* argv[])
{Std_ReturnType result;pthread_t acquisitionThread;/* 1. 注册信号处理器 */signal(SIGINT, SignalHandler);signal(SIGTERM, SignalHandler);/* 2. 初始化ara::com */result = AraComRuntime_Initialize();if (result != E_OK) {fprintf(stderr, "Failed to initialize ara::com\n");return -1;}/* 3. 加载Manifest配置 */ManifestConfig_Type config;result = LoadManifestConfiguration("/etc/aracom/radar_provider_manifest.json",&config);if (result != E_OK) {fprintf(stderr, "Failed to load manifest\n");AraComRuntime_Deinitialize();return -1;}/* 4. 初始化所有服务实例 */result = InitializeAllServiceInstances();if (result != E_OK) {fprintf(stderr, "Failed to initialize service instances\n");AraComRuntime_Deinitialize();return -1;}/* 5. 创建RadarService Skeleton */radarSkeleton = RadarServiceSkeleton_Create(/* serviceInstanceId */ 1);if (radarSkeleton == NULL) {fprintf(stderr, "Failed to create RadarService skeleton\n");AraComRuntime_Deinitialize();return -1;}/* 6. 注册方法处理器 */RadarServiceSkeleton_RegisterSetRadarModeHandler(radarSkeleton,SetRadarModeHandler);/* 7. 提供服务 */result = RadarServiceSkeleton_OfferService(radarSkeleton);if (result != E_OK) {fprintf(stderr, "Failed to offer service\n");RadarServiceSkeleton_Delete(radarSkeleton);AraComRuntime_Deinitialize();return -1;}printf("RadarService is running...\n");/* 8. 启动雷达数据采集线程 */pthread_create(&acquisitionThread, NULL, RadarAcquisitionThread, NULL);/* 9. 主循环 */while (isRunning) {/* 处理ara::com事件 */AraComRuntime_ProcessEvents();OsDelay(10);}/* 10. 清理 */printf("\nShutting down...\n");/* 等待采集线程结束 */pthread_join(acquisitionThread, NULL);/* 停止提供服务 */RadarServiceSkeleton_StopOfferService(radarSkeleton);/* 删除Skeleton */RadarServiceSkeleton_Delete(radarSkeleton);/* 清理ara::com */AraComRuntime_Deinitialize();printf("Shutdown complete.\n");return 0;
}
代码示例: Consumer应用程序
/* Consumer应用程序 - main.c */#include "ara_com.h"
#include "radar_service.h"/* 全局变量 */
static boolean isRunning = TRUE;
static RadarServiceProxy_Type* radarProxy;/* 信号处理 */
void SignalHandler(int sig)
{if (sig == SIGINT || sig == SIGTERM) {isRunning = FALSE;}
}/* RadarObjects事件回调 */
void OnRadarObjectsReceived(const RadarObjects* objects)
{printf("Received %u radar objects:\n", objects->numObjects);for (uint16 i = 0; i < objects->numObjects; i++) {const RadarObject* obj = &objects->objects[i];printf(" Object %u: distance=%.2f m, velocity=%.2f m/s, angle=%.2f deg\n",i,obj->distance,obj->velocity,obj->angle);}
}/* 主函数 */
int main(int argc, char* argv[])
{Std_ReturnType result;ServiceHandleContainer_Type handles;/* 1. 注册信号处理器 */signal(SIGINT, SignalHandler);signal(SIGTERM, SignalHandler);/* 2. 初始化ara::com */result = AraComRuntime_Initialize();if (result != E_OK) {fprintf(stderr, "Failed to initialize ara::com\n");return -1;}/* 3. 加载Manifest配置 */ManifestConfig_Type config;result = LoadManifestConfiguration("/etc/aracom/radar_consumer_manifest.json",&config);if (result != E_OK) {fprintf(stderr, "Failed to load manifest\n");AraComRuntime_Deinitialize();return -1;}/* 4. 初始化所有服务实例 */result = InitializeAllServiceInstances();if (result != E_OK) {fprintf(stderr, "Failed to initialize service instances\n");AraComRuntime_Deinitialize();return -1;}/* 5. 查找RadarService */printf("Finding RadarService...\n");result = AraComServiceDiscovery_FindService("RadarService/1",&handles);if (result != E_OK || handles.numHandles == 0) {fprintf(stderr, "RadarService not found\n");AraComRuntime_Deinitialize();return -1;}printf("RadarService found!\n");/* 6. 创建RadarService Proxy */radarProxy = RadarServiceProxy_Create(handles.handles[0]);if (radarProxy == NULL) {fprintf(stderr, "Failed to create RadarService proxy\n");AraComRuntime_Deinitialize();return -1;}/* 7. 订阅RadarObjects事件 */result = RadarServiceProxy_SubscribeRadarObjects(radarProxy,OnRadarObjectsReceived,/* queue size */ 10);if (result != E_OK) {fprintf(stderr, "Failed to subscribe to RadarObjects event\n");RadarServiceProxy_Delete(radarProxy);AraComRuntime_Deinitialize();return -1;}printf("Subscribed to RadarObjects event\n");/* 8. 调用SetRadarMode方法 */SetRadarModeResult methodResult;result = RadarServiceProxy_SetRadarMode(radarProxy,RADAR_MODE_LONG_RANGE,&methodResult);if (result == E_OK && methodResult.success) {printf("Radar mode set to LONG_RANGE\n");} else {fprintf(stderr, "Failed to set radar mode\n");}/* 9. 主循环 */printf("Receiving radar data... (Press Ctrl+C to exit)\n");while (isRunning) {/* 处理ara::com事件 (包括接收数据) */AraComRuntime_ProcessEvents();OsDelay(10);}/* 10. 清理 */printf("\nShutting down...\n");/* 取消订阅 */RadarServiceProxy_UnsubscribeRadarObjects(radarProxy);/* 删除Proxy */RadarServiceProxy_Delete(radarProxy);/* 清理ara::com */AraComRuntime_Deinitialize();printf("Shutdown complete.\n");return 0;
}
9. 总结
9.1 关键特性
AUTOSAR Adaptive Platform与DDS Security的集成提供了以下关键特性:
9.1.1 透明的安全通信
- 应用层透明: 应用程序使用标准的ara::com API,无需显式处理安全逻辑
- 自动加密: 数据在DDS层自动加密和解密,根据Governance Document配置
- 自动认证: Domain Participants之间自动进行身份认证和密钥交换
9.1.2 灵活的安全策略
- 域级策略: 通过Governance Document定义域级安全策略
- Topic级策略: 为每个Topic单独配置安全属性
- 细粒度权限: 通过Permissions Document精确控制发布和订阅权限
9.1.3 标准合规性
- AUTOSAR标准: 完全符合AUTOSAR Adaptive Platform规范
- DDS Security标准: 符合OMG DDS Security v1.1标准
- 加密标准: 支持X.509证书、PKCS#7签名等业界标准
9.1.4 性能优化
- 硬件加速: 可利用硬件安全模块(HSM)进行加密操作
- 会话密钥: 使用高效的对称加密进行数据传输
- 选择性保护: 可针对不同Topic选择不同的保护级别
9.2 应用场景
9.2.1 车内ECU通信
场景描述: 车内不同安全域的ECU之间的安全通信
安全需求:
- 防止未授权ECU加入网络
- 保护关键传感器数据(雷达、相机)的机密性
- 确保控制命令的完整性和来源认证
解决方案:
- 使用DDS Security的Authentication Plugin验证ECU身份
- 对传感器数据启用加密保护(
data_protection_kind=ENCRYPT
) - 对控制命令启用签名保护(
data_protection_kind=SIGN_WITH_ORIGIN_AUTHENTICATION
)
9.2.2 车对车(V2V)通信
场景描述: 车辆之间交换位置、速度等信息
安全需求:
- 验证消息来源车辆的身份
- 防止消息重放攻击
- 确保消息完整性
解决方案:
- 使用PKI证书体系进行车辆身份认证
- 启用消息签名和时间戳验证
- 配置短有效期的Permissions Document
9.2.3 云端连接
场景描述: 车辆与云端服务器之间的通信
安全需求:
- 双向身份认证
- 端到端加密
- 定期密钥更新
解决方案:
- 使用mutual TLS进行Authentication
- 启用端到端加密保护
- 配置密钥更新策略
9.2.4 软件更新(OTA)
场景描述: 远程更新ECU软件
安全需求:
- 验证更新包来源
- 确保更新包完整性
- 防止回滚攻击
解决方案:
- 对更新数据启用签名验证
- 使用版本号和有效期控制
- 配置严格的Permissions规则
9.3 最佳实践
9.3.1 证书管理
建议:
- 使用分层PKI架构(Root CA → Intermediate CA → Entity Certificates)
- 定期更新证书,设置合理的有效期
- 使用Hardware Security Module(HSM)保护私钥
- 实施证书撤销机制(CRL或OCSP)
代码示例: 证书更新流程
/* 证书更新流程 */
Std_ReturnType UpdateCertificate(const char* newCertPath,const char* newKeyPath)
{Std_ReturnType result;/* 1. 验证新证书 */result = VerifyNewCertificate(newCertPath);if (result != E_OK) {return E_NOT_OK;}/* 2. 备份当前证书 */result = BackupCurrentCertificate();if (result != E_OK) {return E_NOT_OK;}/* 3. 安装新证书 */result = InstallNewCertificate(newCertPath, newKeyPath);if (result != E_OK) {/* 回滚 */RestoreBackupCertificate();return E_NOT_OK;}/* 4. 重新初始化DDS Security */result = ReinitializeDdsSecurity();if (result != E_OK) {/* 回滚 */RestoreBackupCertificate();ReinitializeDdsSecurity();return E_NOT_OK;}return E_OK;
}
9.3.2 权限配置
建议:
- 遵循最小权限原则,只授予必要的权限
- 使用deny_rule显式拒绝敏感操作
- 定期审查和更新Permissions Document
- 为不同的安全域使用不同的Permissions Document
示例: 最小权限配置
<grant name="MinimalGrant"><subject_name>CN=ConsumerECU, O=OEM, C=DE</subject_name><validity><not_before>2024-01-01T00:00:00</not_before><not_after>2025-01-01T00:00:00</not_after></validity><!-- 只允许订阅特定Topic --><allow_rule><domains><id>0</id></domains><subscribe><topics><topic>ara.com://services/RadarService/*/RadarObjects</topic></topics></subscribe></allow_rule><!-- 显式拒绝发布 --><deny_rule><domains><id>0</id></domains><publish><topics><topic>*</topic></topics></publish></deny_rule><default>DENY</default>
</grant>
9.3.3 性能优化
建议:
- 根据数据敏感性选择合适的保护级别
- 对高频、低敏感度数据使用
SIGN
而非ENCRYPT
- 使用
BEST_EFFORT
Reliability QoS for实时性要求高的数据 - 配置合理的History深度,避免内存浪费
性能对比:
保护类型 | CPU开销 | 网络开销 | 安全级别 | 适用场景 |
---|---|---|---|---|
NONE | 最低 | 无 | 无保护 | 非敏感数据 |
SIGN | 低 | 小 | 完整性 | 状态信息 |
SIGN_WITH_ORIGIN_AUTHENTICATION | 中 | 中 | 完整性+认证 | 控制命令 |
ENCRYPT | 高 | 大 | 机密性+完整性 | 敏感数据 |
9.3.4 故障处理
建议:
- 实施完善的错误检测和日志记录
- 配置合理的超时时间
- 实现降级策略(如认证失败时的处理)
- 定期进行安全审计
代码示例: 故障处理
/* 安全通信故障处理 */
Std_ReturnType HandleSecurityFailure(SecurityFailureTypeEnum failureType,const char* errorDetails)
{/* 1. 记录安全事件 */LogSecurityEvent(SECURITY_EVENT_LEVEL_ERROR,failureType,errorDetails);/* 2. 根据故障类型采取措施 */switch (failureType) {case SECURITY_FAILURE_AUTHENTICATION:/* 认证失败 - 拒绝通信 */BlockRemoteParticipant();SendSecurityAlert(ALERT_AUTHENTICATION_FAILED);break;case SECURITY_FAILURE_CERTIFICATE_EXPIRED:/* 证书过期 - 尝试更新 */TriggerCertificateUpdate();break;case SECURITY_FAILURE_PERMISSION_DENIED:/* 权限拒绝 - 记录并通知 */NotifySecurityAdministrator();break;case SECURITY_FAILURE_DECRYPTION:/* 解密失败 - 丢弃消息 */DiscardMessage();break;default:/* 未知错误 */return E_NOT_OK;}/* 3. 更新安全指标 */UpdateSecurityMetrics(failureType);return E_OK;
}
9.3.5 安全配置审查清单
在部署DDS Security之前,请检查以下项目:
证书和密钥:
- 所有证书均由可信CA签名
- 证书有效期设置合理(不要过长)
- 私钥使用HSM或安全存储保护
- 已配置证书撤销机制
Governance Document:
-
allow_unauthenticated_participants
设置为FALSE
-
enable_join_access_control
设置为TRUE
- 所有敏感Topic配置了适当的保护类型
- Topic访问规则覆盖所有必要的Topic
Permissions Document:
- 每个Participant的权限遵循最小权限原则
-
default
策略设置为DENY
- 有效期设置合理
- Subject Name与身份证书匹配
QoS配置:
- QoS Profile包含所有必需的安全属性
- 文件路径正确且可访问
- Reliability和Durability QoS与应用需求匹配
运行时:
- 实施了证书验证
- 配置了适当的超时时间
- 实现了错误处理和日志记录
- 定期进行安全审计
结语
AUTOSAR Adaptive Platform与DDS Security的集成为车载通信提供了强大的安全保障。通过本文档详细介绍的配置流程、代码示例和最佳实践,开发者可以:
- 理解架构: 掌握DDS Security在AUTOSAR Adaptive Platform中的集成架构
- 配置安全: 正确配置Governance Document和Permissions Document
- 实现代码: 编写安全的Provider和Consumer应用程序
- 优化性能: 根据实际需求选择合适的安全策略
- 故障处理: 实施完善的错误检测和恢复机制
随着智能网联汽车的发展,车载通信安全将变得越来越重要。掌握DDS Security技术,对于开发安全、可靠的汽车软件系统至关重要。
版权所有 © 2024 | 用于技术学习和参考