示例#1
0
bdoc::X509Cert bdoc::Signature::getSigningCertificate() const
{
    const dsig::X509DataType::X509CertificateType&
    certBlock = getSigningX509CertificateType();

    return X509Cert(
               (const unsigned char*)certBlock.data(), certBlock.size());
}
示例#2
0
/**
 * @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();
}
示例#3
0
/**
 * 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);
}
示例#4
0
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;
}
示例#5
0
/**
 *
 * @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);
}