diff options
4 files changed, 92 insertions, 31 deletions
diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx index 4e31c40bf733..bdf8000d886b 100644 --- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx +++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx @@ -432,6 +432,30 @@ Sequence< Reference < XCertificate > > SecurityEnvironment_NssImpl::buildCertifi return Sequence< Reference < XCertificate > >(); } +X509Certificate_NssImpl* SecurityEnvironment_NssImpl::createAndAddCertificateFromPackage( + const css::uno::Sequence<sal_Int8>& raDERCertificate, + OUString const & raString) +{ + auto pCertificateBytes = reinterpret_cast<char *>(const_cast<sal_Int8 *>(raDERCertificate.getConstArray())); + CERTCertificate* pCERTCertificate = CERT_DecodeCertFromPackage(pCertificateBytes, raDERCertificate.getLength()); + + if (!pCERTCertificate) + return nullptr; + + OString aTrustString = OUStringToOString(raString, RTL_TEXTENCODING_ASCII_US); + + CERTCertTrust aTrust; + if (CERT_DecodeTrustString(&aTrust, aTrustString.getStr()) != SECSuccess) + return nullptr; + + if (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), pCERTCertificate, &aTrust) != SECSuccess) + return nullptr; + + X509Certificate_NssImpl* pX509Certificate = new X509Certificate_NssImpl(); + pX509Certificate->setCert(pCERTCertificate); + return pX509Certificate; +} + X509Certificate_NssImpl* SecurityEnvironment_NssImpl::createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& aDerCertificate) { X509Certificate_NssImpl* pX509Certificate = nullptr; @@ -816,68 +840,71 @@ xmlSecKeysMngrPtr SecurityEnvironment_NssImpl::createKeysManager() { // Adopt the private key of the signing certificate, if it has any. if (auto pCertificate = dynamic_cast<X509Certificate_NssImpl*>(m_xSigningCertificate.get())) { - if (auto pCERTCertificate = const_cast<CERTCertificate*>(pCertificate->getNssCert())) + SECKEYPrivateKey* pPrivateKey = pCertificate->getPrivateKey(); + if (pPrivateKey) { - if (pCERTCertificate && pCERTCertificate->slot) - { - SECKEYPrivateKey* pPrivateKey = PK11_FindPrivateKeyFromCert(pCERTCertificate->slot, pCERTCertificate, nullptr); - xmlSecKeyDataPtr pKeyData = xmlSecNssPKIAdoptKey(pPrivateKey, nullptr); - xmlSecKeyPtr pKey = xmlSecKeyCreate(); - xmlSecKeySetValue(pKey, pKeyData); - xmlSecNssAppDefaultKeysMngrAdoptKey(pKeysMngr, pKey); - } - else - { - SAL_WARN("xmlsecurity.xmlsec", "Can't get the private key from the certificate."); - } + xmlSecKeyDataPtr pKeyData = xmlSecNssPKIAdoptKey(pPrivateKey, nullptr); + xmlSecKeyPtr pKey = xmlSecKeyCreate(); + xmlSecKeySetValue(pKey, pKeyData); + xmlSecNssAppDefaultKeysMngrAdoptKey(pKeysMngr, pKey); + } + else + { + SAL_WARN("xmlsecurity.xmlsec", "Can't get the private key from the certificate."); } } - return pKeysMngr ; + return pKeysMngr; } + void SecurityEnvironment_NssImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) { if( pKeysMngr != nullptr ) { xmlSecKeysMngrDestroy( pKeysMngr ) ; } } -uno::Reference<security::XCertificate> SecurityEnvironment_NssImpl::createDERCertificateWithPrivateKey( - Sequence<sal_Int8> const & raDERCertificate, Sequence<sal_Int8> const & raPrivateKey) +SECKEYPrivateKey* SecurityEnvironment_NssImpl::insertPrivateKey(css::uno::Sequence<sal_Int8> const & raPrivateKey) { - SECStatus nStatus = SECSuccess; - PK11SlotInfo* pSlot = PK11_GetInternalKeySlot(); + if (!pSlot) - return uno::Reference<security::XCertificate>(); + return nullptr; SECItem pDerPrivateKeyInfo; pDerPrivateKeyInfo.data = reinterpret_cast<unsigned char *>(const_cast<sal_Int8 *>(raPrivateKey.getConstArray())); pDerPrivateKeyInfo.len = raPrivateKey.getLength(); - const unsigned int keyUsage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; + const unsigned int aKeyUsage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; SECKEYPrivateKey* pPrivateKey = nullptr; bool bPermanent = false; bool bSensitive = false; - nStatus = PK11_ImportDERPrivateKeyInfoAndReturnKey( + SECStatus nStatus = PK11_ImportDERPrivateKeyInfoAndReturnKey( pSlot, &pDerPrivateKeyInfo, nullptr, nullptr, bPermanent, bSensitive, - keyUsage, &pPrivateKey, nullptr); + aKeyUsage, &pPrivateKey, nullptr); if (nStatus != SECSuccess) - return uno::Reference<security::XCertificate>(); + return nullptr; + + return pPrivateKey; +} + +uno::Reference<security::XCertificate> SecurityEnvironment_NssImpl::createDERCertificateWithPrivateKey( + Sequence<sal_Int8> const & raDERCertificate, Sequence<sal_Int8> const & raPrivateKey) +{ + + SECKEYPrivateKey* pPrivateKey = insertPrivateKey(raPrivateKey); if (!pPrivateKey) return uno::Reference<security::XCertificate>(); - X509Certificate_NssImpl* pX509Certificate = createX509CertificateFromDER(raDERCertificate); + X509Certificate_NssImpl* pX509Certificate = createAndAddCertificateFromPackage(raDERCertificate, "TCu,Cu,Tu"); + if (!pX509Certificate) return uno::Reference<security::XCertificate>(); - addCryptoSlot(pSlot); - - CERTCertificate* pCERTCertificate = const_cast<CERTCertificate*>(pX509Certificate->getNssCert()); - pCERTCertificate->slot = pSlot; + pX509Certificate->setCustomPrivateKey(pPrivateKey); return pX509Certificate; } diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx index 6c6160fc2009..9829c9129771 100644 --- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx +++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx @@ -128,9 +128,15 @@ private: static void destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) ; private: + void updateSlots(); - X509Certificate_NssImpl* createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& aDerCertificate); + X509Certificate_NssImpl* createAndAddCertificateFromPackage( + const css::uno::Sequence<sal_Int8>& raDerCertificate, + OUString const & raString); + SECKEYPrivateKey* insertPrivateKey(css::uno::Sequence<sal_Int8> const & raPrivateKey); + + X509Certificate_NssImpl* createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& raDerCertificate); /// @throws css::uno::Exception /// @throws css::uno::RuntimeException diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx index 53449e9c0900..35a3e841e6f4 100644 --- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx +++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx @@ -46,7 +46,8 @@ using ::com::sun::star::security::XCertificate ; using ::com::sun::star::util::DateTime ; X509Certificate_NssImpl::X509Certificate_NssImpl() : - m_pCert( nullptr ) + m_pCert(nullptr), + m_pPrivateKey(nullptr) { } @@ -331,6 +332,29 @@ void X509Certificate_NssImpl::setRawCert( const Sequence< sal_Int8 >& rawCert ) m_pCert = cert ; } +void X509Certificate_NssImpl::setCustomPrivateKey(SECKEYPrivateKey* pPrivateKey) +{ + m_pPrivateKey = pPrivateKey; +} + +SECKEYPrivateKey* X509Certificate_NssImpl::getPrivateKey() +{ + if (m_pPrivateKey) + { + return m_pPrivateKey; + } + else + { + if (m_pCert && m_pCert->slot) + { + SECKEYPrivateKey* pPrivateKey = PK11_FindPrivateKeyFromCert(m_pCert->slot, m_pCert, nullptr); + if (pPrivateKey) + return pPrivateKey; + } + } + return nullptr; +} + /* XUnoTunnel */ sal_Int64 SAL_CALL X509Certificate_NssImpl::getSomething( const Sequence< sal_Int8 >& aIdentifier ) { if( aIdentifier.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx index 6e2b8a472068..64c76972bf83 100644 --- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx +++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx @@ -40,7 +40,8 @@ class X509Certificate_NssImpl : public ::cppu::WeakImplHelper< css::lang::XServiceInfo > , public xmlsecurity::Certificate { private: - CERTCertificate* m_pCert ; + CERTCertificate* m_pCert; + SECKEYPrivateKey* m_pPrivateKey; public: X509Certificate_NssImpl() ; @@ -93,8 +94,11 @@ class X509Certificate_NssImpl : public ::cppu::WeakImplHelper< //Helper methods void setCert( CERTCertificate* cert ) ; const CERTCertificate* getNssCert() const ; + /// @throws css::uno::RuntimeException void setRawCert( const css::uno::Sequence< sal_Int8 >& rawCert ) ; + void setCustomPrivateKey(SECKEYPrivateKey* pPrivateKey); + SECKEYPrivateKey* getPrivateKey(); // XServiceInfo virtual OUString SAL_CALL getImplementationName() override; |