Пример #1
0
std::string bdoc::X509Cert::getRsaExponent() const
{
	EVP_PKEY* pubKey = getPublicKey();
	if (EVP_PKEY_type(pubKey->type) != EVP_PKEY_RSA) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Public key is not a RSA key.");
	}

	int bufSize = BN_num_bytes(pubKey->pkey.rsa->e);

	if (bufSize <= 0) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Failed to extract RSA exponent.");
	}

	std::string exp(bufSize, '\0');

	if (BN_bn2bin(pubKey->pkey.rsa->e, (unsigned char *)&exp[0]) <= 0) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Failed to extract RSA exponent.");
	}

	EVP_PKEY_free(pubKey);
	return exp;
}
Пример #2
0
bdoc::OCSP* bdoc::SignatureValidator::prepare()
{
    _signingCert = _sig->getSigningCertificate();

    std::string issuer = _signingCert.getIssuerName();
    int pos = issuer.find("CN=", 0) + 3;
    std::string issure_cn =
        issuer.substr(pos, issuer.find(",", pos) - pos);
    if (!_conf->hasOCSPConf(issure_cn)) {
        THROW_STACK_EXCEPTION("Failed to find ocsp responder.");
    }

    OCSPConf ocspConf = _conf->getOCSPConf(issure_cn);

    _issuerX509 = _conf->getCertStore()->
                  getCert(*(_signingCert.getIssuerNameAsn1()));
    if (_issuerX509 == NULL) {
        THROW_STACK_EXCEPTION("Failed to load issuer certificate.");
    }

    _ocspCerts = X509Cert::loadX509Stack(ocspConf.cert);

    OCSP *ocsp = new OCSP(ocspConf.url);
    ocsp->setSkew(ocspConf.skew);
    ocsp->setMaxAge(ocspConf.maxAge);
    ocsp->setOCSPCerts(_ocspCerts);

    return ocsp;
}
Пример #3
0
void bdoc::Signature::checkSignatureValue()
{
    X509Cert cert(getSigningCertificate());

    const dsig::SignatureMethodType::AlgorithmType&
    algorithmType = getSignatureMethodAlgorithmType();
    const char* algorithmUri = algorithmType.c_str();

    // Get hash method URI from signature method URI.
    signatureMethod sm;
    hashMethod hm;
    safeBuffer hashMethodUri;
    if (!XSECmapURIToSignatureMethods(XMLString::transcode(algorithmUri), sm, hm)
            || !hashMethod2URI(hashMethodUri, hm)) {
        THROW_STACK_EXCEPTION("Couldn't extract hash method from "
                              "signature method URI '%s'.", algorithmUri);
    }

    std::auto_ptr<Digest> calc = Digest::create(hashMethodUri.rawCharBuffer());
    std::vector<unsigned char> digest =
        calcDigestOnNode(calc.get(), DSIG_NAMESPACE, "SignedInfo");

    std::vector<unsigned char> signatureValue = getSignatureValue();

    if (!cert.verifySignature(calc->getMethod(), calc->getSize(), digest,
                              signatureValue)) {
        THROW_STACK_EXCEPTION("Signature is not valid.");
    }
}
Пример #4
0
void bdoc::XAdES132Signature::checkQualifyingProperties() const
{
    dsig::ObjectType::QualifyingPropertiesSequence const&
    qProps = _sign->object()[0].qualifyingProperties();

    if (qProps.size() != 1) {
        THROW_STACK_EXCEPTION(
            "Number of QualifyingProperties is %d, must be 1",
            qProps.size());
    }

    if (qProps[0].target() != "#" + _sign->id().get()) {
        THROW_STACK_EXCEPTION(
            "QualifyingProperties target is not Signature");
    }

    checkSignedSignatureProperties();

    if (qProps[0].unsignedProperties().present()) {
        xades132::QualifyingPropertiesType::UnsignedPropertiesType
        uProps = qProps[0].unsignedProperties().get();
        if (uProps.unsignedDataObjectProperties().present()) {
            THROW_STACK_EXCEPTION(
                "unexpected UnsignedDataObjectProperties in "
                "Signature");
        }
    }
}
Пример #5
0
std::string bdoc::X509Cert::getRsaModulus() const
{
	EVP_PKEY* pubKey = getPublicKey();
	if (EVP_PKEY_type(pubKey->type) != EVP_PKEY_RSA) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Public key is not a RSA key.");
	}


	int bufSize = BN_num_bytes(pubKey->pkey.rsa->n);

	if (bufSize <= 0) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Failed to extract RSA modulus.");
	}

	std::string modulus(bufSize, '\0');

	if (BN_bn2bin(pubKey->pkey.rsa->n, (unsigned char*)&modulus[0]) <= 0) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Failed to extract RSA modulus.");
	}

	EVP_PKEY_free(pubKey);
	return modulus;
}
Пример #6
0
bdoc::X509Cert::X509Cert(const unsigned char* bytes, size_t len) :
	cert(NULL)
{
	if (bytes == NULL) {
		THROW_STACK_EXCEPTION("No bytes given to parse X509.");
	}

	d2i_X509(&cert, &bytes, len);
	if (cert == NULL) {
		THROW_STACK_EXCEPTION("Failed to parse X509 certificate from bytes given: %s", ERR_reason_error_string(ERR_get_error()));
	}
}
Пример #7
0
void bdoc::SHA1Digest::update(const unsigned char* data, unsigned long length)
{
	if (data == NULL) {
		THROW_STACK_EXCEPTION("Can not update digest value from NULL pointer.");
	}

	if (!digest.empty()) {
		THROW_STACK_EXCEPTION("Digest is already finalized, can not update it.");
	}

	if (SHA1_Update(&ctx, static_cast<const void*>(data), length) != 1) {
		THROW_STACK_EXCEPTION("Failed to update SHA1 digest value: %s", ERR_reason_error_string(ERR_get_error()));
	}
}
Пример #8
0
void bdoc::Signature::validateIdentifier() const
{
    const dsig::SignatureType::IdOptional& idOptional = _sign->id();
    if (!idOptional.present()) {
        THROW_STACK_EXCEPTION(
            "Signature element mandatory attribute "
            "'Id' is missing");
    }

    if (idOptional.get().empty()) {
        THROW_STACK_EXCEPTION(
            "Signature element mandatory attribute 'Id' is empty");
    }
}
Пример #9
0
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");
    }
}
Пример #10
0
X509* bdoc::X509Cert::loadX509(const std::string& path)
{
	BIO* file = BIO_new(BIO_s_file());
	BIO_scope fileScope(&file);
	if (file == NULL) {
		THROW_STACK_EXCEPTION("Failed to open X.509 certificate file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	if (BIO_read_filename(file, path.c_str()) <= 0) {
		THROW_STACK_EXCEPTION("Failed to open X.509 certificate file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	// Parse X.509 certificate from file.
	return PEM_read_bio_X509(file, NULL, NULL, NULL);
}
Пример #11
0
std::vector<unsigned char> bdoc::X509Cert::encodeDER() const
{
	int bufSize = i2d_X509(cert, NULL);
	if (bufSize < 0) {
		THROW_STACK_EXCEPTION("Failed to encode X509 cert to DER.");
	}

	std::vector<unsigned char> derEncodedX509(bufSize, 0);

	unsigned char* pBuf = &derEncodedX509[0];
	bufSize = i2d_X509(cert, &pBuf);
	if (bufSize < 0) {
		THROW_STACK_EXCEPTION("Failed to encode X509 cert to DER.");
	}

	return derEncodedX509;
}
Пример #12
0
X509* bdoc::X509Cert::copyX509(X509* cert)
{
	X509* copy = X509_dup(cert);
	if (copy == NULL) {
		THROW_STACK_EXCEPTION("Failed to copy X509 certificate: %s", ERR_reason_error_string(ERR_get_error()));
	}

	return copy;
}
Пример #13
0
bool bdoc::X509Cert::isValid() const
{
	int notBefore = X509_cmp_current_time(cert->cert_info->validity->notBefore);
	int notAfter = X509_cmp_current_time(cert->cert_info->validity->notAfter);
	if (notBefore == 0 || notAfter == 0) {
		THROW_STACK_EXCEPTION("Failed to validate cert", ERR_reason_error_string(ERR_get_error()));
	}
	return notBefore < 0 && notAfter > 0;
}
Пример #14
0
std::string bdoc::X509Cert::getSubject() const
{
	X509_NAME* subject = X509_get_subject_name(cert);
	if (subject == NULL) {
	   THROW_STACK_EXCEPTION("Failed to convert X.509 certificate subject: %s", ERR_reason_error_string(ERR_get_error()));
	}

	return toString(subject);
}
Пример #15
0
std::string bdoc::X509Cert::getIssuerName() const
{
	X509_NAME* issuerName = X509_get_issuer_name(cert);
	if (issuerName == NULL) {
		THROW_STACK_EXCEPTION("Failed to convert X.509 certificate issuer name: %s", ERR_reason_error_string(ERR_get_error()));
	}

	return toString(issuerName);
}
Пример #16
0
void bdoc::XAdES111Signature::getOCSPResponseValue(std::vector<unsigned char>& data) const
{
    if (!unsignSigProps().present()) {
        THROW_STACK_EXCEPTION("Unsigned signature properties missing");
    }

    if (!unsignSigProps()->revocationValues().present()) {
        THROW_STACK_EXCEPTION("Revocation values missing");
    }

    xades111::RevocationValuesType t = unsignSigProps()->revocationValues().get();

    xades111::OCSPValuesType tt = t.oCSPValues().get();
    xades111::OCSPValuesType::EncapsulatedOCSPValueType resp = tt.encapsulatedOCSPValue()[0];

    data.resize(resp.size());
    std::copy(resp.data(), resp.data()+resp.size(), data.begin());
}
Пример #17
0
void bdoc::Signature::checkReferenceToSigProps(
    const bdoc::dsig::ReferenceType& refType)
{
    const dsig::ReferenceType::URIOptional& uriOpt = refType.uRI();

    if (!uriOpt.present()) {
        THROW_STACK_EXCEPTION(
            "SignedInfo reference to SignedProperties does not "
            "have attribute 'URI'");
    }

    const dsig::DigestMethodType& digestMethod = refType.digestMethod();
    const dsig::DigestMethodType::AlgorithmType&
    algorithm = digestMethod.algorithm();

    if (!Digest::isSupported(algorithm)) {
        THROW_STACK_EXCEPTION(
            "reference to SignedProperties digest method "
            "algorithm '%s' is not supported", algorithm.c_str());
    }

    const dsig::DigestValueType& digestValue = refType.digestValue();

    std::auto_ptr<Digest> calc =
        Digest::create(refType.digestMethod().algorithm());

    std::vector<unsigned char> calculatedDigestValue =
        calcDigestOnNode(
            calc.get(), xadesnamespace(), "SignedProperties");

    if (digestValue.begin() + calculatedDigestValue.size()
            != digestValue.end()) {
        THROW_STACK_EXCEPTION(
            "SignedProperties digest lengths do not match");
    }

    for (size_t i = 0; i < calculatedDigestValue.size(); i++) {
        const char* dv = digestValue.begin() + i;
        if (*dv != static_cast<char>(calculatedDigestValue[i])) {
            THROW_STACK_EXCEPTION(
                "SignedProperties digest values do not match");
        }
    }
}
Пример #18
0
EVP_PKEY* bdoc::X509Cert::getPublicKey() const
{
	EVP_PKEY* pubKey = X509_get_pubkey(cert);
	if (pubKey == NULL) {
		EVP_PKEY_free(pubKey);
		THROW_STACK_EXCEPTION("Unable to load public key: %s",
				ERR_reason_error_string(ERR_get_error()));
	}
	return pubKey;
}
Пример #19
0
void bdoc::XAdES111Signature::checkSignedSignatureProperties() const
{
    dsig::SignatureType::ObjectSequence& os = _sign->object();
    if (os.empty()) {
        THROW_STACK_EXCEPTION("Signature block 'Object' is missing.");
    }
    else if (os.size() != 1) {
        THROW_STACK_EXCEPTION(
            "Signature block contains more than one "
            "'Object' block.");
    }
    dsig::ObjectType& o = os[0];

    dsig::ObjectType::QualifyingProperties1Sequence&
    qpSeq = o.qualifyingProperties1();
    if (qpSeq.empty()) {
        THROW_STACK_EXCEPTION(
            "Signature block 'QualifyingProperties' is missing.");
    }
    else if (qpSeq.size() != 1) {
        THROW_STACK_EXCEPTION(
            "Signature block 'Object' contains more than one "
            "'QualifyingProperties' block.");
    }
    xades111::QualifyingPropertiesType& qp = qpSeq[0];

    xades111::QualifyingPropertiesType::SignedPropertiesOptional&
    signedPropsOptional = qp.signedProperties();

    if (!signedPropsOptional.present()) {
        THROW_STACK_EXCEPTION(
            "QualifyingProperties block 'SignedProperties' "
            "is missing.");
    }
    xades111::SignedPropertiesType& signedProps = qp.signedProperties().get();

    xades111::SignedSignaturePropertiesType& signedSigProps =
        signedProps.signedSignatureProperties();

    xades111::SignedSignaturePropertiesType::
    SignaturePolicyIdentifierType
    policyOpt = signedSigProps.signaturePolicyIdentifier();
}
Пример #20
0
void bdoc::Signature::checkReferencesToDocs(
    dsig::SignedInfoType::ReferenceSequence& refSeq) const
{
    _bdoc->checkDocumentsBegin();

    for (dsig::SignedInfoType::ReferenceSequence::const_iterator
            itRef = refSeq.begin(); itRef != refSeq.end(); itRef++) {

        const dsig::ReferenceType& refType = (*itRef);

        if (!isReferenceToSigProps(refType)) {
            const dsig::ReferenceType::URIOptional&
            uriOpt = refType.uRI();
            if (!uriOpt.present()) {
                THROW_STACK_EXCEPTION(
                    "Document reference is missing "
                    "attribute 'URI'");
            }
            std::string docRefUri(uriOpt.get());

            // file names in manifest do not have '/' at front
            if (!docRefUri.empty() && docRefUri[0] == '/') {
                docRefUri.erase(0, 1);
            }

            const dsig::DigestMethodType&
            digestMethod = refType.digestMethod();

            const dsig::DigestMethodType::AlgorithmType&
            algorithmType = digestMethod.algorithm();

            const dsig::DigestValueType&
            digestValueType = refType.digestValue();

            _bdoc->checkDocument(
                docRefUri, algorithmType, digestValueType);
        }
    }

    if (!_bdoc->checkDocumentsResult()) {
        THROW_STACK_EXCEPTION("Document references didn't match");
    }
}
Пример #21
0
bdoc::dsig::KeyInfoType& bdoc::Signature::keyInfo() const
{
    dsig::SignatureType::KeyInfoOptional&
    keyInfoOptional = _sign->keyInfo();
    if (!keyInfoOptional.present()) {
        THROW_STACK_EXCEPTION(
            "Signature mandatory element KeyInfo is missing");
    }

    return keyInfoOptional.get();
}
Пример #22
0
void bdoc::Signature::checkReferences()
{
    dsig::SignedInfoType& signedInfo = _sign->signedInfo();
    dsig::SignedInfoType::ReferenceSequence&
    refSeq = signedInfo.reference();

    if (refSeq.size() != (_bdoc->documentCount() + 1)) {
        // we require exactly one ref to every document,
        // plus one ref to the SignedProperties
        THROW_STACK_EXCEPTION(
            "Number of references in SignedInfo is invalid: "
            "found %d, expected %d",
            refSeq.size(), _bdoc->documentCount() + 1);
    }

    bool gotSignatureRef = false;
    for (dsig::SignedInfoType::ReferenceSequence::const_iterator
            itRef = refSeq.begin(); itRef != refSeq.end(); itRef++) {

        const dsig::ReferenceType& refType = (*itRef);

        if (isReferenceToSigProps(refType)) {
            // the one and only reference to SignedProperties
            if (gotSignatureRef) {
                THROW_STACK_EXCEPTION(
                    "SignedInfo element refers to more "
                    "than one SignedProperties");
            }
            gotSignatureRef = true;
            checkReferenceToSigProps(refType);
        }
    }

    if (!gotSignatureRef) {
        THROW_STACK_EXCEPTION(
            "SignedInfo does not contain reference to "
            "SignedProperties");
    }

    checkReferencesToDocs(refSeq);
}
Пример #23
0
std::auto_ptr<bdoc::Digest> bdoc::Digest::create(int method)
{
	switch(method) {
	default:
		THROW_STACK_EXCEPTION("Digest method '%s' is not supported.", OBJ_nid2sn(method));
	case NID_sha1: return std::auto_ptr<Digest>(new SHA1Digest);
	case NID_sha224: return std::auto_ptr<Digest>(new SHA224Digest);
	case NID_sha256: return std::auto_ptr<Digest>(new SHA256Digest);
	case NID_sha384: return std::auto_ptr<Digest>(new SHA384Digest);
	case NID_sha512: return std::auto_ptr<Digest>(new SHA512Digest);
	}
}
Пример #24
0
bdoc::xades111::UnsignedPropertiesType::UnsignedSignaturePropertiesOptional&
bdoc::XAdES111Signature::unsignSigProps() const
{
    if (!_sign->object()[0].qualifyingProperties1()[0].
            unsignedProperties().present()) {
        THROW_STACK_EXCEPTION("Missing UnsignedProperties");
    }

    return _sign->object()[0].qualifyingProperties1()[0].
           unsignedProperties()->
           unsignedSignatureProperties();
}
Пример #25
0
void bdoc::Signature::checkSignatureMethod() const
{
    dsig::SignatureMethodType::AlgorithmType&
    algorithmType = getSignatureMethodAlgorithmType();
    if (algorithmType != URI_ID_RSA_SHA1
            && algorithmType != URI_ID_RSA_SHA224
            && algorithmType != URI_ID_RSA_SHA256) {
        THROW_STACK_EXCEPTION(
            "Unsupported SignedInfo signature method \"%s\"",
            algorithmType.c_str());
    }
}
Пример #26
0
bool bdoc::X509Cert::verify(X509_STORE* aStore, struct tm* tm) const
{
	if (aStore == NULL) {
		THROW_STACK_EXCEPTION("Invalid argument to verify");
	}

	X509_STORE* store = aStore;
	X509_STORE** ppStore = NULL;
	X509_STORE_scope xst(ppStore);

	X509_STORE_CTX *csc = X509_STORE_CTX_new();
	X509_STORE_CTX_scope csct(&csc);
	if (csc == NULL) {
		THROW_STACK_EXCEPTION("Failed to create X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error()));
	}

	X509* x = getX509();
	X509_scope xt(&x);
	if (!X509_STORE_CTX_init(csc, store, x, NULL)) {
		THROW_STACK_EXCEPTION("Failed to init X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error()));
	}

	if (tm != NULL) {
		time_t t = timegm(tm);
		if (t == -1) {
			THROW_STACK_EXCEPTION("Given time cannot be represented as calendar time");
		}

		X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(csc);
		if (param == NULL) {
			THROW_STACK_EXCEPTION("Failed to retrieve X509_STORE_CTX verification parameters %s",
				ERR_reason_error_string(ERR_get_error()));
		}
		X509_VERIFY_PARAM_set_time(param, t);
	}

	int ok = X509_verify_cert(csc);

	if (ok != 1) {
		int err = X509_STORE_CTX_get_error(csc);
		X509Cert cause(X509_STORE_CTX_get_current_cert (csc));
		std::ostringstream s;
		s << "Unable to verify " << cause.getSubject();
		s << ". Cause: " << X509_verify_cert_error_string(err);
		switch (err) {
			case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
				{
					THROW_STACK_EXCEPTION("Certificate issuer missing: %s", s.str().c_str());
				}
			default: THROW_STACK_EXCEPTION(s.str().c_str()); break;
		}
	}

	return (ok == 1);
}
Пример #27
0
std::string bdoc::X509Cert::toString(X509_NAME* name)
{
	BIO* mem = BIO_new(BIO_s_mem());
	BIO_scope memScope(&mem);
	if (mem == NULL) {
		THROW_STACK_EXCEPTION("Failed to allocate memory for X509_NAME conversion: %s", ERR_reason_error_string(ERR_get_error()));
	}

	if (X509_NAME_print_ex(mem, name, 0, XN_FLAG_RFC2253) < 0) {
		THROW_STACK_EXCEPTION("Failed to convert X509_NAME struct to string: %s", ERR_reason_error_string(ERR_get_error()));
	}

	// Read the converted string from buffer.
	char buf[128];
	int bytesRead;
	std::string str;
	while ((bytesRead = BIO_gets(mem, &buf[0], sizeof(buf))) > 0) {
		str.append(buf);
	}

	return str;
}
Пример #28
0
std::auto_ptr<xercesc::DOMDocument> bdoc::Signature::createDom() const
{

    try {
        std::auto_ptr<xercesc::XercesDOMParser>
        parser(new xercesc::XercesDOMParser());

        parser->setValidationScheme(
            xercesc::XercesDOMParser::Val_Always);

        parser->setDoNamespaces(true);

        xercesc::MemBufInputSource memIS((const XMLByte*)_xml, _xml_len, "test", false);

        parser->parse(memIS);
        xercesc::DOMNode* dom = parser->getDocument()->cloneNode(true);

        return std::auto_ptr<xercesc::DOMDocument>
               (static_cast<xercesc::DOMDocument*>(dom));
    }
    catch (const xercesc::XMLException& e) {
        char* tmp = xercesc::XMLString::transcode(e.getMessage());
        std::string msg(tmp);
        xercesc::XMLString::release(&tmp);
        THROW_STACK_EXCEPTION(
            "Failed to parse signature XML: %s", msg.c_str());
    }
    catch (const xercesc::DOMException& e) {
        char* tmp = xercesc::XMLString::transcode(e.msg);
        std::string msg(tmp);
        xercesc::XMLString::release(&tmp);
        THROW_STACK_EXCEPTION(
            "Failed to parse signature XML: %s", msg.c_str());
    }
    catch (...) {
        THROW_STACK_EXCEPTION("Failed to parse signature XML.");
    }
    return std::auto_ptr<xercesc::DOMDocument>(NULL);
}
Пример #29
0
bdoc::dsig::X509DataType::X509CertificateType&
bdoc::Signature::getSigningX509CertificateType() const
{
    dsig::SignatureType::KeyInfoOptional&
    keyInfoOptional = _sign->keyInfo();
    if (!keyInfoOptional.present()) {
        THROW_STACK_EXCEPTION(
            "Signature does not contain signer certificate");
    }

    dsig::KeyInfoType& keyInfo = keyInfoOptional.get();

    dsig::KeyInfoType::X509DataSequence& x509DataSeq = keyInfo.x509Data();
    if (x509DataSeq.empty()) {
        THROW_STACK_EXCEPTION(
            "Signature does not contain signer certificate");
    }
    else if (x509DataSeq.size() != 1) {
        THROW_STACK_EXCEPTION(
            "Signature contains more than one signer certificate");
    }
    dsig::X509DataType& x509Data = x509DataSeq.front();

    dsig::X509DataType::X509CertificateSequence&
    x509CertSeq = x509Data.x509Certificate();
    if (x509CertSeq.empty()) {
        THROW_STACK_EXCEPTION(
            "Signature does not contain signer certificate");
    }
    else if (x509CertSeq.size() != 1) {
        THROW_STACK_EXCEPTION(
            "Signature contains more than one signer certificate");
    }
    dsig::X509DataType::X509CertificateType&
    certBase64Buf = x509CertSeq.front();

    return certBase64Buf;
}
Пример #30
0
STACK_OF(X509)* bdoc::X509Cert::loadX509Stack(const std::string& path)
{
	STACK_OF(X509)* stack = sk_X509_new_null();
	if (stack == NULL) {
		THROW_STACK_EXCEPTION("Failed to create X.509 certificate stack.");
	}

	BIO* file = BIO_new(BIO_s_file());
	BIO_scope fileScope(&file);
	if (file == NULL) {
		THROW_STACK_EXCEPTION("Failed to open X.509 certificates file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	if (BIO_read_filename(file, path.c_str()) <= 0) {
		THROW_STACK_EXCEPTION("Failed to open X.509 certificates file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	STACK_OF(X509_INFO)* certsInfo = PEM_X509_INFO_read_bio(file, NULL, NULL, NULL);
	if (certsInfo == NULL) {
		THROW_STACK_EXCEPTION("Failed to read X.509 certificates from file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	for (int i = 0; i < sk_X509_INFO_num(certsInfo); i++) {
		X509_INFO* xi = sk_X509_INFO_value(certsInfo, i);
		if (xi->x509 != NULL) {
			sk_X509_push(stack, xi->x509);
			xi->x509 = NULL;
		}
	}

	sk_X509_INFO_pop_free(certsInfo, X509_INFO_free);

	return stack;
}