Swift(Linux):提取CMS / PKCS#7 Certs并验证容器签名?
我正在
Swift 4中编写一组将在
Linux上运行的服务.我需要做的一件事是接收使用加密消息语法(CMS)格式进行数字签名的有效负载,提取用于签名的证书,然后验证签名.我知道Linux上的Swift不包含用于此类事情的Security或CommonCrypto框架,所以我在OpenSSL中链接以尝试帮助解决这个问题.我距离我的C/C++编程时间已经有两年了,所以我很乐意承认我对这部分代码感到满意.
我有2个简单的类来充当OpenSSL BIO和PKCS7数据结构的包装器.它们看起来像这样: import Foundation import OpenSSL public final class BIOWrapper { public var bio = BIO_new(BIO_s_mem()) public init(data: Data) { data.withUnsafeBytes { pointer -> Void in BIO_write(self.bio,pointer,Int32(data.count)) } } public init() {} deinit { BIO_free(self.bio) } } public final class PKCS7Wrapper { public var pkcs7: UnsafeMutablePointer<PKCS7> public init(pkcs7: UnsafeMutablePointer<PKCS7>) { self.pkcs7 = pkcs7 } deinit { PKCS7_free(self.pkcs7) } } 我能够成功提取PKCS#7容器数据,并使用以下代码验证数据类型代码值是否为NID_pkcs7_signed: let reqData = Data(bytes: reqBytes) guard reqData.count > 0 else { print("Empty request body") return nil } let bioWrapper = BIOWrapper(data: reqData) guard let container = d2i_PKCS7_bio(bioWrapper.bio,nil) else { print("No container") return nil } let pkcs7Wrapper = PKCS7Wrapper(pkcs7: container) let dataTypeCode = OBJ_obj2nid((pkcs7Wrapper.pkcs7.pointee.d.sign).pointee.contents.pointee.type) print("dataTypeCode : (dataTypeCode)") if dataTypeCode == NID_pkcs7_data { print("GOT DATA!") } else { print("Didn't get data") return nil } let pkcs7SignedTypeCode = OBJ_obj2nid(pkcs7Wrapper.pkcs7.pointee.type) if let signed = pkcs7SignedTypeCode == NID_pkcs7_signed { print("Signed : (signed)") } 但是,我现在已经到了我被卡住的地步.如何从PKCS#7有效负载中获取X.509证书数据?我可以看到pkcs7Wrapper.pkcs7.pointee.d.sign.pointee.cert数据结构应该包含证书链数据.其数据类型为UnsafeMutablePointer< stack_st_x509>我认为一旦我在内存中获得X.509证书数据,我就可以找出使用OpenSSL的PKCS7_verify方法的代码.我只是不知道该怎么做. 我发现this resource讨论验证OSX / iOS上的收据,这些收据涉及很多相同的问题.他们从文件系统获取X.509证书,并将数据传递到PKCS7_verify方法.我只需要知道如何从PKCS#7容器中获取证书数据. 谁能帮我这个?我认识到从Swift调用C并不理想,但是由于没有一个良好的Swift安全/加密框架,我不知道任何其他选项. 解决方法
答案的核心部分在于您链接的代码:
let store = X509_STORE_new() X509_STORE_add_cert(store,appleRootX509) OpenSSL_add_all_digests() let result = PKCS7_verify(receiptPKCS7,nil,store,0) if result != 1 { log.atLevelDebug(id: 0,source: "Main",message: "Receipt signature verification failed") exit(errorCode) } 您似乎缺少的是您不必自己从PKCS7数据中提取X509证书. PKCS7_verify function will do it作为验证的一部分:
因此,您需要自己加载的唯一证书是您在linked code中从文件系统加载的根证书. 如果由于某种原因仍然需要Swift解决方案从PKCS7数据中提取证书,则必须为PKCS7构建ASN.1解析器.不确定这是否适用于Swift,this simple code是快速搜索产生的,this是对PKCS7数据的一个很好的描述. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |