#include <securityd/SecOCSPRequest.h>
#include <Security/SecCertificateInternal.h>
#include <AssertMacros.h>
#include <utilities/debugging.h>
#include <security_asn1/SecAsn1Coder.h>
#include <security_asn1/ocspTemplates.h>
#include <security_asn1/oidsalg.h>
#include <security_asn1/oidsocsp.h>
#include <CommonCrypto/CommonDigest.h>
#include <stdlib.h>
#include "SecInternal.h"
static CFDataRef _SecOCSPRequestCopyDEREncoding(SecOCSPRequestRef this) {
SecAsn1OCSPSignedRequest signedReq = {};
SecAsn1OCSPTbsRequest *tbs = &signedReq.tbsRequest;
SecAsn1OCSPRequest singleReq = {};
SecAsn1OCSPCertID *certId = &singleReq.reqCert;
SecAsn1OCSPRequest *reqArray[2] = { &singleReq, NULL };
uint8_t version = 0;
SecAsn1Item vers = {1, &version};
CFDataRef der = NULL;
SecAsn1CoderRef coder = NULL;
CFDataRef issuerNameDigest;
CFDataRef serial;
CFDataRef issuerPubKeyDigest;
certId->algId.algorithm = CSSMOID_SHA1;
static uint8_t nullParam[2] = {5, 0};
certId->algId.parameters.Data = nullParam;
certId->algId.parameters.Length = sizeof(nullParam);
issuerNameDigest = SecCertificateCopyIssuerSHA1Digest(this->certificate);
serial = SecCertificateCopySerialNumber(this->certificate);
issuerPubKeyDigest = SecCertificateCopyPublicKeySHA1Digest(this->issuer);
certId->issuerNameHash.Length = CC_SHA1_DIGEST_LENGTH;
certId->issuerNameHash.Data = (uint8_t *)CFDataGetBytePtr(issuerNameDigest);
certId->issuerPubKeyHash.Length = CC_SHA1_DIGEST_LENGTH;
certId->issuerPubKeyHash.Data = (uint8_t *)CFDataGetBytePtr(issuerPubKeyDigest);
certId->serialNumber.Length = CFDataGetLength(serial);
certId->serialNumber.Data = (uint8_t *)CFDataGetBytePtr(serial);
tbs->version = &vers;
tbs->requestList = reqArray;
require_noerr(SecAsn1CoderCreate(&coder), errOut);
SecAsn1Item encoded;
require_noerr(SecAsn1EncodeItem(coder, &signedReq,
kSecAsn1OCSPSignedRequestTemplate, &encoded), errOut);
der = CFDataCreate(kCFAllocatorDefault, encoded.Data,
encoded.Length);
errOut:
if (coder)
SecAsn1CoderRelease(coder);
CFReleaseSafe(issuerNameDigest);
CFReleaseSafe(serial);
CFReleaseSafe(issuerPubKeyDigest);
return der;
}
SecOCSPRequestRef SecOCSPRequestCreate(SecCertificateRef certificate,
SecCertificateRef issuer) {
SecOCSPRequestRef this;
require(this = (SecOCSPRequestRef)calloc(1, sizeof(struct __SecOCSPRequest)),
errOut);
this->certificate = certificate;
this->issuer = issuer;
return this;
errOut:
if (this) {
SecOCSPRequestFinalize(this);
}
return NULL;
}
CFDataRef SecOCSPRequestGetDER(SecOCSPRequestRef this) {
CFDataRef der = this->der;
if (!der) {
this->der = der = _SecOCSPRequestCopyDEREncoding(this);
}
return der;
}
void SecOCSPRequestFinalize(SecOCSPRequestRef this) {
CFReleaseSafe(this->der);
free(this);
}