bdoc::X509Cert bdoc::Signature::getSigningCertificate() const { const dsig::X509DataType::X509CertificateType& certBlock = getSigningX509CertificateType(); return X509Cert( (const unsigned char*)certBlock.data(), certBlock.size()); }
/** * @return returns OCSP certificate */ digidoc::X509Cert digidoc::SignatureTM::getOCSPCertificate() const { const xades::UnsignedSignaturePropertiesType::CertificateValuesType::EncapsulatedX509CertificateSequence &certs = unsignedSignatureProperties()->certificateValues()[0].encapsulatedX509Certificate(); xades::UnsignedSignaturePropertiesType::CertificateValuesType::EncapsulatedX509CertificateSequence::const_iterator i = certs.begin(); try { for( ; i != certs.end(); ++i ) { if( i->id() && i->id().get().find( "RESPONDER_CERT" ) != std::string::npos ) return X509Cert( std::vector<unsigned char>( i->data(), i->data() + i->size() ) ); } if( certs.begin() != certs.end() ) return X509Cert( std::vector<unsigned char>( certs.begin()->data(), certs.begin()->data() + certs.begin()->size() ) ); } catch( const Exception & ) {} return X509Cert(); }
/** * Sign the signature using BDOC-BES profile. Sets required fields, * calculates digests and finally signs the signature object using * the provided <code>signer</code> implementation. * * @param signer signer that signs the signature object. * @throws SignatureException exception is throws if signing failed. */ void digidoc::SignatureBES::sign(Signer* signer) throw(SignatureException, SignException) { std::vector<unsigned char> sha = prepareSignedInfo(signer); Signer::Digest sigDigestSha = { signer->type(), &sha[0], (unsigned int)sha.size() }; // Sign the calculated SHA digest and add the signature value (SHA-RSA) to the signature. int size = 128; try { size = X509Cert(signer->getCert()).getPaddingSize(); } catch( const IOException &e ) { THROW_SIGNEXCEPTION_CAUSE( e, "Failed to sign document" ); } std::vector<unsigned char> buf(size); Signer::Signature signatureShaRsa = { &buf[0], (unsigned int)buf.size() }; signer->sign(sigDigestSha, signatureShaRsa); setSignatureValue(signatureShaRsa); }
int digidoc::EstEIDSigner::type() const { int result = digidoc::Digest::toMethod( Conf::getInstance()->getSignatureUri() ); if( result == NID_sha1 ) return result; char buf[50]; bool found = false; CERTIFICATEPOLICIES *cp = (CERTIFICATEPOLICIES*)X509_get_ext_d2i(getCert(), NID_certificate_policies, 0, 0); for( int i = 0; i < sk_POLICYINFO_num(cp); ++i ) { memset(buf, 0, 50); int len = OBJ_obj2txt(buf, 50, sk_POLICYINFO_value(cp, i)->policyid, 1); if(len != NID_undef && (strncmp(buf, "1.3.6.1.4.1.10015.1.2.", 22) == 0 || strncmp(buf, "1.3.6.1.4.1.10015.3.2.", 22) == 0)) found = true; } sk_POLICYINFO_pop_free(cp, POLICYINFO_free); if(!found) return X509Cert(getCert()).getPaddingSize() > 128 ? result : NID_sha224; return result; }
/** * * @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); }