bdoc::OCSP::CertStatus bdoc::SignatureValidator::validateBESOnline() { std::auto_ptr<OCSP> ocsp(prepare()); std::auto_ptr<Digest> sigCalc = Digest::create(_conf->getDigestURI()); sigCalc->update(_sig->getSignatureValue()); return ocsp->checkCert(_signingCert.getX509(), _issuerX509, sigCalc->getDigest(), _ocspResponse, _producedAt); }
void bdoc::SignatureValidator::validateTMOffline() { // 1. Check OCSP response (RevocationValues) was signed by OCSP server // 2. OCSP server certificate is trusted? // 3. Check that nonce field in OCSP response is same as // CompleteRevocationRefs->DigestValue // 4. Recalculate hash of signature and compare with nonce std::auto_ptr<OCSP> ocsp(prepare()); _sig->getOCSPResponseValue(_ocspResponse); ocsp->verifyResponse(_ocspResponse); std::vector<unsigned char> respNonce = ocsp->getNonce(_ocspResponse); xml_schema::Uri method = _sig->ocspDigestAlgorithm(); std::auto_ptr<Digest> calc = Digest::create(std::string(method)); calc->update(_sig->getSignatureValue()); std::vector<unsigned char> nonce = calc->getDigest(); if (nonce != respNonce) { THROW_STACK_EXCEPTION( "Calculated signature hash doesn't match to OCSP " "responder nonce field"); } std::vector<unsigned char> revocationOCSPRefValue(0); std::string ocspResponseHashUri; _sig->getRevocationOCSPRef(revocationOCSPRefValue, ocspResponseHashUri); std::auto_ptr<Digest> ocspResponseCalc = Digest::create(ocspResponseHashUri); ocspResponseCalc->update(_ocspResponse); std::vector<unsigned char> ocspResponseHash = ocspResponseCalc->getDigest(); if (ocspResponseHash != revocationOCSPRefValue) { THROW_STACK_EXCEPTION( "OCSPRef value doesn't match with hash of OCSP " "response"); } }
/** * Do TM offline validations. * <ul> * <li>Validate BES offline</li> * <li>Check OCSP response (RevocationValues) was signed by trusted OCSP server</li> * <li>Check that nonce field in OCSP response is same as CompleteRevocationRefs->DigestValue</li> * <li>Recalculate hash of signature and compare with nonce</li> * </ul> * @throws SignatureException if signature is not valid */ void digidoc::SignatureTM::validateOffline() const throw(SignatureException) { SignatureBES::validateOffline(); // 1. Check OCSP response (RevocationValues) was signed by OCSP server // 2. OCSP server certificate is trusted? // 3. Check that nonce field in OCSP response is same as CompleteRevocationRefs->DigestValue // 4. Recalculate hash of signature and compare with nonce #if 0 Conf* conf = Conf::getInstance(); Conf::OCSPConf ocspConf = conf->getOCSP(getSigningCertificate().getIssuerName()); if(ocspConf.issuer.empty()) { SignatureException e(__FILE__, __LINE__, "Failed to find ocsp responder."); e.setCode( Exception::OCSPResponderMissing ); throw e; } OCSP ocsp(ocspConf.url); STACK_OF(X509)* ocspCerts = 0; try { ocspCerts = X509Cert::loadX509Stack(ocspConf.cert); } catch( const Exception &e ) { SignatureException exception(__FILE__, __LINE__, "OCSP certificate loading failed", e); exception.setCode( Exception::OCSPCertMissing ); throw exception; } X509Stack_scope x509StackScope(&ocspCerts); ocsp.setOCSPCerts(ocspCerts); #else OCSP ocsp; ocsp.setCertStore(digidoc::X509CertStore::getInstance()->getCertStore()); ocsp.setOCSPCerts(digidoc::X509CertStore::getInstance()->getCerts()); #endif std::vector<unsigned char> respBuf; try { getOCSPResponseValue(respBuf); ocsp.verifyResponse(respBuf); } catch( const Exception &e ) { THROW_SIGNATUREEXCEPTION_CAUSE( e, "OCSP response verfiy failed" ); } DEBUG("OCSP response was signed by trusted OCSP responder"); std::vector<unsigned char> respNonce = ocsp.getNonce(respBuf); xml_schema::Uri method = unsignedSignatureProperties()->completeRevocationRefs()[0].oCSPRefs() ->oCSPRef()[0].digestAlgAndValue()->digestMethod().algorithm(); std::auto_ptr<Digest> calc = Digest::create(std::string(method)); calc->update(getSignatureValue()); std::vector<unsigned char> nonce = calc->getDigest(); if(nonce != respNonce) { DEBUGMEM("Calculated signature HASH", &nonce[0], nonce.size()); DEBUGMEM("Response nonce", &respNonce[0], respNonce.size()); THROW_SIGNATUREEXCEPTION("Calculated signature hash doesn't match to OCSP responder nonce field"); } std::vector<unsigned char> revocationOCSPRefValue(0); std::string ocspResponseHashUri; getRevocationOCSPRef(revocationOCSPRefValue, ocspResponseHashUri); std::auto_ptr<Digest> ocspResponseCalc = Digest::create(ocspResponseHashUri); DEBUG("Calculating digest on %d bytes", respBuf.size()); ocspResponseCalc->update(respBuf); std::vector<unsigned char> ocspResponseHash = ocspResponseCalc->getDigest(); if(ocspResponseHash != revocationOCSPRefValue) { DEBUGMEM("Document ocspResponse HASH:", &revocationOCSPRefValue[0], revocationOCSPRefValue.size()); DEBUGMEM("Calculated ocspResponse HASH:", &ocspResponseHash[0], ocspResponseHash.size()); THROW_SIGNATUREEXCEPTION("OCSPRef value doesn't match with hash of OCSP response"); } else { DEBUG("TM signature valid"); } }