📄 osppkcs7.c
字号:
OSPTASN1OBJECT *newObject = OSPC_OSNULL; OSPTASN1OBJECT *contentInfo = OSPC_OSNULL; /*The Signature is a ContentInfo sturcture with a datatype of signedData */ /* Create a parse result for each of the input parameters. Add the result to the results list in the correct order. It will be necessary to call subroutines to build the sub element. The parse results table will have DataReference-able elements attached. Running the parse table through the rules to build the element info list and then traversing the element info list should build an ASN1 encode object. */ /* Signed Data structure will contain element info pointer (null), and a parse results table containing populated data elements with data reference values. */ /* Content type is SignedData. Content may or may not be contained in the signed data structure. */ /* Create a content info object for the signature */ errorcode = OSPPASN1ObjectNew(&contentInfo, OSPEDRID_CONTENTINFO); /* The elements are a contentType OID, and a content element. */ /* Add the content type Element to the result list */ for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++) { switch(i) { case 0: dataRefId = OSPEDRID_CNTINF_CONTENTTYPE; errorcode = OSPPASN1ObjectIdentifierEncode(&newObject, ospvContentTypeId, dataRefId); break; case 1: dataRefId = OSPEDRID_CNTINF_CONTENT; if ((ospvSignatureOnly) && (newObject != OSPC_OSNULL)) { OSPPASN1ElementDelete(&(newObject->ElementInfo), 0); } else { errorcode = OSPPASN1ObjectCopy(&newObject,ospvContent); if(newObject != OSPC_OSNULL) { OSPPASN1ElementDelete(&(newObject->ElementInfo), 0); } } break; case 2: errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE; break; default: errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR; OSPM_DBGERRORLOG(errorcode, "Unknown case encountered encoding PKCS7 ContentInfo."); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Add new object to this object */ if (newObject != OSPC_OSNULL) { errorcode = OSPPASN1ObjectAddChild(contentInfo, newObject, dataRefId); OSPM_FREE(newObject); } } } if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE) { errorcode = OSPC_ERR_NO_ERROR; } if (errorcode == OSPC_ERR_NO_ERROR) { if (ospvContentTypeId == OSPEID_DATA) { tableId = OSPEPTID_CONTENTINFO_DATA; } else if (ospvContentTypeId == OSPEID_SIGNEDDATA) { tableId = OSPEPTID_CONTENTINFO_SIGNEDDATA; } else { errorcode = OSPC_ERR_ASN1_PARSE_ERROR; OSPM_DBGERRORLOG(errorcode, "Unsupported contentInfo type specified"); } if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPPASN1ObjectDeparse(contentInfo, tableId, OSPEDRID_CONTENTINFO); } } if (errorcode == OSPC_ERR_NO_ERROR) { *ospvContentInfo = contentInfo; } else { OSPPASN1ObjectDelete(&contentInfo); /* Do the cleanup stuff here */ } if(newObject != OSPC_OSNULL) { OSPPASN1ObjectDelete(&newObject); } return errorcode;}/* Caller must provide space for content. ospvContentLength should be setto the size of the space provided. An error will occur if the contentcontained in the signature is larger than the space provided.If the signature does not contain the signed content, then the caller willset content to the data that was signed and set content length to thelength of the data being signed. If the signature does contain the signed content, then the call should setcontent to zeros and set contentlength to the size of the content buffer.The content from the signature will be copied to the content buffer and thelength will be changed to the actual length of the content. An error willoccur if the length of the content is larger than the length of the buffer.*/intOSPPPKCS7SignatureParse( OSPTASN1OBJECT **ospvSignatureObject, unsigned char *ospvSignature, unsigned int ospvSignatureLength){ int errorcode = OSPC_ERR_NO_ERROR; OSPTASN1OBJECT *signatureObject = OSPC_OSNULL; OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL; OSPTASN1PARSERESULT *parseResults = OSPC_OSNULL; if ((ospvSignatureObject == OSPC_OSNULL) || (ospvSignature == OSPC_OSNULL) || (ospvSignatureLength == 0)) { errorcode = OSPC_ERR_PKCS7_INVALID_POINTER; OSPM_DBGERRORLOG(errorcode, "Invalid input or output pointers"); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Decode the signature into element and build element list */ errorcode = OSPPASN1ElementDecode(ospvSignature, &eInfo, 0); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Parse the element list to validate structure and get cross reference list elements */ errorcode = OSPPASN1ElementParse( eInfo, OSPEPTID_CONTENTINFO_SIGNEDDATA, OSPC_OSNULL, &parseResults, OSPC_ASN1_DATAREFID_CONTENTINFO); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Create the signatureObject object that will contain the decoded/parsed signature */ errorcode = OSPPASN1ObjectCreate(&signatureObject, eInfo, parseResults); } if (errorcode == OSPC_ERR_NO_ERROR) { *ospvSignatureObject = signatureObject; } return errorcode;} intOSPPPKCS7SignatureGetContent( OSPTASN1OBJECT *ospvSignatureObject, unsigned char **ospvContent, unsigned int *ospvContentLength, OSPTASN1ELEMENTINFO **el ){ int errorcode = OSPC_ERR_NO_ERROR; OSPTASN1ELEMENTINFO *contentElement = OSPC_OSNULL; unsigned char *content = OSPC_OSNULL; unsigned int contentLength = 0; /* Extract content from signature object */ errorcode = OSPPASN1ObjectGetElementByDataRef( ospvSignatureObject, &contentElement, OSPEDRID_SIG_SGNDAT_DATA); if (errorcode == OSPC_ERR_NO_ERROR) { /* Now we have the data element that should contain the data that was signed. */ /* Get pointer to data and set length */ errorcode = OSPPASN1ElementGetContentData(contentElement, &content, &contentLength); if (errorcode == OSPC_ERR_NO_ERROR) { *ospvContent = content; *ospvContentLength = contentLength; } if(OSPC_OSNULL!=el) /* !!! PS */ { *el=contentElement; } } return errorcode;}intOSPPPKCS7SignatureVerify( OSPTASN1OBJECT *ospvSignatureObject, unsigned char *ospvContent, unsigned int ospvContentLength, OSPTASN1OBJECT *ospvAuthorityCertificates[], unsigned int ospvNumberOfAuthorityCertificates){ int errorcode = OSPC_ERR_NO_ERROR; OSPTASN1OBJECT *digestAlgorithmId = OSPC_OSNULL; OSPTASN1OBJECT *encryptionAlgorithm = OSPC_OSNULL; OSPTASN1OBJECT *encryptedDigest = OSPC_OSNULL; OSPTASN1OBJECT *subjPubKeyInfo = OSPC_OSNULL; OSPTASN1OBJECT *signerCertificate = OSPC_OSNULL; OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL; unsigned char *contentDigest = OSPC_OSNULL; unsigned int contentDigestLength = 0; OSPTASN1OBJECT *decryptedDigestObject = OSPC_OSNULL; OSPTASN1OBJECT *digestInfo = OSPC_OSNULL; unsigned char *decryptedDigest = OSPC_OSNULL; unsigned int decryptedDigestLength = 0; if ((ospvContent == OSPC_OSNULL) || (ospvContentLength == 0)) { errorcode = OSPC_ERR_PKCS7_INVALID_POINTER; OSPM_DBGERRORLOG(errorcode, "Content buffer pointer is null, or length is 0"); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Now we have the content that was signed and the length. Need to generate a digest of it for comparison against the signature */ if (errorcode == OSPC_ERR_NO_ERROR) { /* Get the digest algorithm id from the signature object. */ errorcode = OSPPASN1ObjectCopyElementObject( &digestAlgorithmId, ospvSignatureObject, OSPEDRID_SIG_SGNDAT_SGNINF_DIGESTALGORITHM); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Create a local Digest Info object to compare to results of decryption. */ errorcode = OSPPPKCS7DigestInfoCreate(&digestInfo, digestAlgorithmId, ospvContent, ospvContentLength); if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPPASN1ObjectGetElementInfo(digestInfo, &eInfo); if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPPASN1ElementGetElementData(eInfo, &contentDigest, &contentDigestLength); } } } } if (errorcode == OSPC_ERR_NO_ERROR) { /* Ok, now we have a digest of the content, Decrypt the signature to get the digest that was encrypted and compare the two digests */ errorcode = OSPPASN1ObjectCopyElementObject(&encryptionAlgorithm, ospvSignatureObject, OSPEDRID_SIG_SGNDAT_SGNINF_DIGENCRYPTALG); if (errorcode == OSPC_ERR_NO_ERROR) { /* Get the signature next */ errorcode = OSPPASN1ObjectCopyElementObject(&encryptedDigest, ospvSignatureObject, OSPEDRID_SIG_SGNDAT_SGNINF_ENCRYPTEDDIGEST); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Get the signer public key from the signers certificate, Only have ONE certificate in signatures, so it is NOT necessary to search for certificate, In the future this might be necessary if certificate chains and/or multiple signers are allowed. This is where the code would be enhanced......BKL */ errorcode = OSPPASN1ObjectCopyElementObject(&subjPubKeyInfo, ospvSignatureObject, OSPEDRID_SIG_SGNDAT_CERTIFICATE_SUBJPUBKEYINFO); } if (errorcode == OSPC_ERR_NO_ERROR) { /* Have the public key data */ errorcode = OSPPCryptoDecrypt(&decryptedDigestObject, encryptionAlgorithm, encryptedDigest, subjPubKeyInfo); } } if (errorcode == OSPC_ERR_NO_ERROR) { /* Now we have a decrypted digest in object form and the digest generated from the content - compare them */ errorcode = OSPPASN1ObjectGetElementInfo(decryptedDigestObject, &eInfo); if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPPASN1ElementGetContentData(eInfo, &decryptedDigest, &decryptedDigestLength); } if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPC_ERR_PKCS7_INVALID_SIGNATURE; if (decryptedDigestLength == contentDigestLength) { if (OSPM_MEMCMP(decryptedDigest, contentDigest, contentDigestLength) == 0) { errorcode = OSPC_ERR_NO_ERROR; } } } } if (errorcode == OSPC_ERR_NO_ERROR) { /* Signature is good. Now test signer certificate to make sure it is valid and properly signed and authorized */ /* Get the signer certificate */ errorcode = OSPPASN1ObjectCopyElementObject(&signerCertificate, ospvSignatureObject, OSPEDRID_SIG_SGNDAT_CERTIFICATE); if (errorcode == OSPC_ERR_NO_ERROR) { int ix=0; /* Test valid signer certificate against CA certificates */ errorcode = OSPPX509CertValidateCertificate(signerCertificate, ospvAuthorityCertificates, ospvNumberOfAuthorityCertificates,&ix); } if(OSPC_OSNULL!=signerCertificate) /* !!! PS */ { OSPPASN1ElementDelete(&(signerCertificate->ParseResults->ElementInfo),0); OSPPASN1ObjectDelete(&signerCertificate); } } if(OSPC_OSNULL!=subjPubKeyInfo) /* !!! PS */ { OSPPASN1ElementDelete(&(subjPubKeyInfo->ParseResults->ElementInfo),0); OSPPASN1ObjectDelete(&subjPubKeyInfo); } if(OSPC_OSNULL!=digestAlgorithmId) /* !!! PS */ { OSPPASN1ElementDelete(&(digestAlgorithmId->ParseResults->ElementInfo),0); OSPPASN1ObjectDelete(&digestAlgorithmId); } if(OSPC_OSNULL!=encryptionAlgorithm) /* !!! PS */ { OSPPASN1ElementDelete(&(encryptionAlgorithm->ParseResults->ElementInfo),0); OSPPASN1ObjectDelete(&encryptionAlgorithm); } if(OSPC_OSNULL!=encryptedDigest) /* !!! PS */ { OSPPASN1ElementDelete(&(encryptedDigest->ParseResults->ElementInfo),0); OSPPASN1ObjectDelete(&encryptedDigest); } if(OSPC_OSNULL!=decryptedDigestObject) /* !!! PS */ { OSPPASN1ObjectDelete(&decryptedDigestObject); } if(OSPC_OSNULL!=digestInfo) /* !!! PS */ { OSPPASN1ObjectDelete(&digestInfo); } return errorcode;} /* OSPPPKCS7SignatureVerify *//* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -