/** * * return * @throws SignatureException */ digidoc::OCSP::CertStatus digidoc::SignatureBES::validateOnline() const throw(SignatureException) { // FIXME: Add exception handling. // Get signing signature. X509Cert cert = getSigningCertificate(); // Get issuer certificate. X509* issuerCert = X509CertStore::getInstance()->getCert(*(cert.getIssuerNameAsn1())); X509_scope issuerCertScope(&issuerCert); if(issuerCert == NULL) { THROW_SIGNATUREEXCEPTION("Failed to load issuer certificate."); } Conf* conf = Conf::getInstance(); // Get OCSP responder certificate. // FIXME: throws IOException, handle it Conf::OCSPConf ocspConf = conf->getOCSP(cert.getIssuerName()); if(ocspConf.issuer.empty()) { SignatureException e(__FILE__, __LINE__, "Failed to find ocsp responder."); e.setCode( Exception::OCSPResponderMissing ); throw e; } STACK_OF(X509)* ocspCerts = X509Cert::loadX509Stack(ocspConf.cert); X509Stack_scope ocspCertsScope(&ocspCerts); // Check the certificate validity from OCSP server. try { OCSP ocsp; ocsp.setSkew(120);//XXX: load from conf ocsp.setOCSPCerts(ocspCerts); ocsp.setUrl(ocspConf.url); std::auto_ptr<Digest> calc = Digest::create(); calc->update(getSignatureValue()); return ocsp.checkCert(cert.getX509(), issuerCert, calc->getDigest()); } catch(const IOException& e) { THROW_SIGNATUREEXCEPTION("Failed to check the certificate validity from OCSP server."); } catch(const OCSPException& e) { THROW_SIGNATUREEXCEPTION("Failed to check the certificate validity from OCSP server."); } return digidoc::OCSP::GOOD; }
/** * * @param signer * @throws SignatureException */ void digidoc::SignatureTM::sign(Signer* signer) throw(SignatureException, SignException) { DEBUG("SignatureTM::sign()"); // Sign with BES profile. SignatureBES::sign(signer); DEBUG("BES signature successful."); // Calculate NONCE value. std::auto_ptr<Digest> calc = Digest::create(); calc->update(getSignatureValue()); std::vector<unsigned char> nonce = calc->getDigest(); DEBUGMEM("Calculated signature HASH (nonce):", &nonce[0], nonce.size()); // Get issuer certificate from certificate store. X509* cert = signer->getCert(); X509Cert cert_(cert); X509* issuer = X509CertStore::getInstance()->getCert(*(cert_.getIssuerNameAsn1())); X509_scope issuerScope(&issuer); if(issuer == NULL) { THROW_SIGNATUREEXCEPTION("Could not find certificate '%s' issuer '%s' in certificate store.", cert_.getSubject().c_str(), cert_.getIssuerName().c_str()); } DEBUG("Signing with X.509 cert {serial=%ld, subject=%s, issuer=%s})", cert_.getSerial(), cert_.getSubject().c_str(), cert_.getIssuerName().c_str()); // Initialize OCSP. DEBUG("Making OCSP request."); Conf* conf = Conf::getInstance(); Conf::OCSPConf ocspConf = conf->getOCSP(cert_.getIssuerName()); if(ocspConf.issuer.empty()) { SignatureException e(__FILE__, __LINE__, "Failed to find ocsp responder."); e.setCode( Exception::OCSPResponderMissing ); throw e; } STACK_OF(X509)* ocspCerts = 0; try { ocspCerts = X509Cert::loadX509Stack(ocspConf.cert); } catch(const IOException& e) { THROW_SIGNATUREEXCEPTION_CAUSE(e, "Failed to load OCSP certificate"); } X509Stack_scope ocspCertsScope(&ocspCerts); OCSP::CertStatus status = OCSP::UNKNOWN; std::vector<unsigned char> ocspResponse; struct tm producedAt; try { OCSP ocsp; ocsp.setOCSPCerts(ocspCerts); ocsp.setUrl(ocspConf.url); ocsp.setMaxAge(2*60); // FIXME: remove or move to conf ocsp.setSkew(15*60); // FIXME: remove or move to conf status = ocsp.checkCert(cert, issuer, nonce, ocspResponse, producedAt); } catch(const IOException& e) { THROW_SIGNATUREEXCEPTION_CAUSE(e, "Failed to get OCSP response"); } catch(const OCSPException& e) { THROW_SIGNATUREEXCEPTION_CAUSE(e, "Failed to get OCSP response"); } switch(status) { case digidoc::OCSP::GOOD: DEBUG("OCSP status: GOOD"); break; case digidoc::OCSP::REVOKED: { DEBUG("OCSP status: REVOKED"); SignatureException e( __FILE__, __LINE__, "Certificate status: revoked" ); e.setCode( Exception::CertificateRevoked ); throw e; break; } case digidoc::OCSP::UNKNOWN: { DEBUG("OCSP status: UNKNOWN"); SignatureException e( __FILE__, __LINE__, "Certificate status: unknown" ); e.setCode( Exception::CertificateUnknown ); throw e; break; } } DEBUG("OCSP response size %d", ocspResponse.size()); // FIXME: get from ocsp instead // FIXME: This file can contain multiple certs. X509Cert class supports only one cert per file // loadX509Stack loads multiple certs from one file // X509* ocspCert = X509Cert::loadX509(Conf::getInstance()->getOCSPCertPath()); X509_scope ocspCertScope(&ocspCert); if(sk_X509_num(ocspCerts) > 1) { ERR("More than one OCSP cert in file."); } X509Cert ocspCert_(sk_X509_value(ocspCerts, 0)); std::auto_ptr<Digest> ocspResponseCalc = Digest::create(); ocspResponseCalc->update(ocspResponse); std::vector<unsigned char> ocspResponseHash = ocspResponseCalc->getDigest(); DEBUGMEM("Calculated ocspResponse HASH:", &ocspResponseHash[0], ocspResponseHash.size()); // Set TM profile signature parameters. createTMProperties(); setOCSPCertificate(ocspCert_); setCACertificate(X509Cert(issuer)); setCompleteRevocationRefs(ocspCert_.getIssuerName(), calc->getUri(), ocspResponseHash, producedAt); setOCSPResponseValue(ocspResponse); }