34#include <rtl/locale.h>
36#include <rtl/ustrbuf.hxx>
37#include <osl/nlsupport.h>
38#include <osl/process.h>
53using ::com::sun::star::security::XCertificate ;
54using ::com::sun::star::util::DateTime ;
63static std::pair< sal_Int32, sal_Int32 >
64findTypeInDN(
const OUString& rRawString, std::u16string_view sTypeName)
66 std::pair< sal_Int32, sal_Int32 > retVal;
67 bool bInEscape =
false;
68 bool bInValue =
false;
70 sal_Int32 nTypeNameStart = 0;
71 sal_Int32
length = rRawString.getLength();
81 std::u16string_view
sType = rRawString.subView(nTypeNameStart,
i - nTypeNameStart);
98 if (
i + 1 <
length && rRawString[
i+1] ==
'"')
101 bInValue = !bInValue;
110 else if (c ==
',' || c ==
'+')
118 nTypeNameStart =
i + 1;
130 if (c !=
' ' && c !=
'\t')
136 sal_Int32 nTypeNameEnd = nTypeNameStart;
141 if (c ==
' ' || c ==
'\t' || c ==
'=')
145 retVal = std::make_pair(nTypeNameStart, nTypeNameEnd);
149 retVal = std::make_pair(-1, -1);
168 std::pair<sal_Int32, sal_Int32 > pairIndex =
findTypeInDN(oldDN,
u"S");
170 if (pairIndex.first != -1)
172 return OUString::Concat(oldDN.subView(0, pairIndex.first))+
"ST"
173 +oldDN.subView(pairIndex.second);
180 m_pCertContext( nullptr )
202 auto serialRange = asNonConstRange(serial);
203 for(
unsigned int i = 0 ;
i <
m_pCertContext->pCertInfo->SerialNumber.cbData ;
i ++ )
214 DWORD cchIssuer = CertNameToStrW(
215 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
217 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
222 if( cchIssuer != 0 ) {
223 auto issuer = std::make_unique<wchar_t[]>(cchIssuer);
225 cchIssuer = CertNameToStrW(
226 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
228 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
229 issuer.get(), cchIssuer
232 if( cchIssuer <= 0 ) {
236 if(issuer.get()[cchIssuer -1] == 0) cchIssuer--;
237 OUString xIssuer(o3tl::toU(issuer.get()), cchIssuer) ;
252 DWORD cchSubject = CertNameToStrW(
253 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
255 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
259 if( cchSubject != 0 )
261 auto subject = std::make_unique<wchar_t[]>(cchSubject);
263 cchSubject = CertNameToStrW(
264 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
266 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
267 subject.get(), cchSubject
270 if( cchSubject <= 0 ) {
274 OUString xSubject(o3tl::toU(subject.get()));
290 SYSTEMTIME explTime ;
292 FILETIME localFileTime;
294 if (FileTimeToLocalFileTime(&(
m_pCertContext->pCertInfo->NotBefore ), &localFileTime))
296 if( FileTimeToSystemTime( &localFileTime, &explTime ) ) {
299 dateTime.Seconds = explTime.wSecond ;
300 dateTime.Minutes = explTime.wMinute ;
301 dateTime.Hours = explTime.wHour ;
302 dateTime.Day = explTime.wDay ;
303 dateTime.Month = explTime.wMonth ;
304 dateTime.Year = explTime.wYear ;
316 SYSTEMTIME explTime ;
318 FILETIME localFileTime;
320 if (FileTimeToLocalFileTime(&(
m_pCertContext->pCertInfo->NotAfter ), &localFileTime))
322 if( FileTimeToSystemTime( &localFileTime, &explTime ) ) {
325 dateTime.Seconds = explTime.wSecond ;
326 dateTime.Minutes = explTime.wMinute ;
327 dateTime.Hours = explTime.wHour ;
328 dateTime.Day = explTime.wDay ;
329 dateTime.Month = explTime.wMonth ;
330 dateTime.Year = explTime.wYear ;
343 auto issuerUidRange = asNonConstRange(issuerUid);
344 for(
unsigned int i = 0 ;
i <
m_pCertContext->pCertInfo->IssuerUniqueId.cbData;
i ++ )
345 issuerUidRange[
i] = *(
m_pCertContext->pCertInfo->IssuerUniqueId.pbData +
i ) ;
356 auto subjectUidRange = asNonConstRange(subjectUid);
357 for(
unsigned int i = 0 ;
i <
m_pCertContext->pCertInfo->SubjectUniqueId.cbData;
i ++ )
358 subjectUidRange[
i] = *(
m_pCertContext->pCertInfo->SubjectUniqueId.pbData +
i ) ;
369 Sequence< Reference< XCertificateExtension > > xExtns(
m_pCertContext->pCertInfo->cExtension ) ;
370 auto pExtns = xExtns.getArray();
376 OUString objId = OUString::createFromAscii( pExtn->pszObjId );
378 if ( objId ==
"2.5.29.17" )
383 xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData,
reinterpret_cast<unsigned char*
>(pExtn->pszObjId), strlen( pExtn->pszObjId ), pExtn->fCritical ) ;
390 return Sequence< Reference< XCertificateExtension > >();
399 CERT_EXTENSION* pExtn = &(
m_pCertContext->pCertInfo->rgExtension[
i] ) ;
404 xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData,
reinterpret_cast<unsigned char*
>(pExtn->pszObjId), strlen( pExtn->pszObjId ), pExtn->fCritical ) ;
418 auto prawCert = rawCert.getArray();
436 if( cert !=
nullptr ) {
455 if( rawCert.getLength() != 0 ) {
456 m_pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING,
reinterpret_cast<const sal_uInt8*
>(&rawCert[0]), rawCert.getLength() ) ;
462 OUString ouOID = OUString::createFromAscii( oid );
465 OUString item = OUString::createFromAscii(
OIDs[
i].oid );
468 return OUString::createFromAscii(
OIDs[
i].desc );
475static css::uno::Sequence< sal_Int8 >
getThumbprint(
const CERT_CONTEXT* pCertContext, DWORD dwPropId)
477 if( pCertContext !=
nullptr )
479 DWORD cbData = dwPropId == CERT_SHA256_HASH_PROP_ID ? 32 : 20;
480 unsigned char fingerprint[32];
481 if (CertGetCertificateContextProperty(pCertContext, dwPropId, fingerprint, &cbData))
484 auto pthumbprint = thumbprint.getArray();
485 for(
unsigned int i = 0 ;
i < cbData ;
i ++ )
487 pthumbprint[
i] = fingerprint[
i];
494 DWORD e = GetLastError();
506 CRYPT_ALGORITHM_IDENTIFIER algorithm =
m_pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm;
519 CRYPT_BIT_BLOB publicKey =
m_pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey;
522 auto keyRange = asNonConstRange(key);
523 for(
unsigned int i = 0 ;
i < publicKey.cbData ;
i++ )
525 keyRange[
i] = *(publicKey.pbData +
i) ;
540 CRYPT_ALGORITHM_IDENTIFIER algorithm =
m_pCertContext->pCertInfo->SignatureAlgorithm;
561 CRYPT_ALGORITHM_IDENTIFIER algorithm =
m_pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm;
562 OString aObjId(algorithm.pszObjId);
563 if (aObjId == szOID_ECC_PUBLIC_KEY)
581 return CertificateKind_X509;
587 CERT_DATA_ENCIPHERMENT_KEY_USAGE |
588 CERT_DIGITAL_SIGNATURE_KEY_USAGE |
589 CERT_KEY_AGREEMENT_KEY_USAGE |
590 CERT_KEY_CERT_SIGN_KEY_USAGE |
591 CERT_KEY_ENCIPHERMENT_KEY_USAGE |
592 CERT_NON_REPUDIATION_KEY_USAGE |
593 CERT_OFFLINE_CRL_SIGN_KEY_USAGE;
597 CERT_EXTENSION* pExtn = CertFindExtension(
602 if (pExtn !=
nullptr)
605 bool rc = CryptDecodeObject(
615 SAL_WARN(
"xmlsecurity.xmlsec",
"CryptDecodeObject failed: " << WindowsErrorString(GetLastError()));
618 std::vector<char>buffer(
length);
620 rc = CryptDecodeObject(
629 CRYPT_BIT_BLOB *blob =
reinterpret_cast<CRYPT_BIT_BLOB*
>(buffer.data());
631 SAL_WARN(
"xmlsecurity.xmlsec",
"CryptDecodeObject failed: " << WindowsErrorString(GetLastError()));
632 else if (blob->cbData == 1)
633 usage = blob->pbData[0];
635 SAL_WARN(
"xmlsecurity.xmlsec",
"CryptDecodeObject(X509_KEY_USAGE) returned unexpected amount of data: " << blob->cbData);
646 return "com.sun.star.xml.security.gpg.XCertificate_MsCryptImpl";
658 return { OUString() };
669 OUStringBuffer buf(rDN.getLength());
671 for (sal_Int32
i = 0;
i < rDN.getLength(); ++
i)
678 if (rDN.getLength() ==
i+1)
689 else if (state == INVALUE)
691 if (rDN[
i] ==
'+' || rDN[
i] ==
',' || rDN[
i] ==
';')
693 buf.append(
"\"" + OUStringChar(rDN[
i]));
696 else if (rDN[
i] ==
'\\')
698 if (rDN.getLength() ==
i+1)
706 buf.append(rDN[
i+1]);
713 if (
i+1 == rDN.getLength())
720 return buf.makeStringAndClear();
726 if (!CertStrToNameW(X509_ASN_ENCODING,
727 reinterpret_cast<LPCWSTR
>(rName.data()), CERT_X500_NAME_STR,
728 nullptr,
nullptr, &rBlob.cbData, &pszError))
730 SAL_INFO(
"xmlsecurity.xmlsec",
"CertStrToNameW failed: " << WindowsErrorString(GetLastError()) <<
"; " << OUString(o3tl::toU(pszError)));
733 rBlob.pbData =
new BYTE[rBlob.cbData];
734 if (!CertStrToNameW(X509_ASN_ENCODING,
735 reinterpret_cast<LPCWSTR
>(rName.data()), CERT_X500_NAME_STR,
736 nullptr, rBlob.pbData, &rBlob.cbData, &pszError))
738 SAL_INFO(
"xmlsecurity.xmlsec",
"CertStrToNameW failed: " << WindowsErrorString(GetLastError()) <<
"; " << OUString(o3tl::toU(pszError)));
745 std::u16string_view
const rName1, std::u16string_view
const rName2,
752 CERT_NAME_BLOB blob1;
757 CERT_NAME_BLOB blob2;
761 ret = CertCompareCertificateName(X509_ASN_ENCODING,
762 &blob1, &blob2) ==
TRUE;
763 delete[] blob2.pbData;
767 CERT_NAME_BLOB blob2compat;
770 delete[] blob1.pbData;
773 ret = CertCompareCertificateName(X509_ASN_ENCODING,
774 &blob1, &blob2compat) ==
TRUE;
775 delete[] blob2compat.pbData;
777 delete[] blob1.pbData;
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getMD5Thumbprint() override
virtual OUString SAL_CALL getSubjectName() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSubjectUniqueID() override
void setMswcryCert(const CERT_CONTEXT *cert)
void setRawCert(css::uno::Sequence< sal_Int8 > const &rawCert)
virtual OUString SAL_CALL getSubjectPublicKeyAlgorithm() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSubjectPublicKeyValue() override
virtual sal_Int32 SAL_CALL getCertificateUsage() override
virtual css::uno::Sequence< sal_Int8 > getSHA256Thumbprint() override
virtual css::security::CertificateKind SAL_CALL getCertificateKind() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSHA1Thumbprint() override
virtual svl::crypto::SignatureMethodAlgorithm getSignatureMethodAlgorithm() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual css::util::DateTime SAL_CALL getNotValidBefore() override
const CERT_CONTEXT * m_pCertContext
virtual OUString SAL_CALL getIssuerName() override
virtual css::uno::Sequence< css::uno::Reference< css::security::XCertificateExtension > > SAL_CALL getExtensions() override
X509Certificate_MSCryptImpl()
virtual OUString SAL_CALL getSignatureAlgorithm() override
virtual ~X509Certificate_MSCryptImpl() override
virtual sal_Int16 SAL_CALL getVersion() override
virtual css::util::DateTime SAL_CALL getNotValidAfter() override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
const CERT_CONTEXT * getMswcryCert() const
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getEncoded() override
virtual css::uno::Reference< css::security::XCertificateExtension > SAL_CALL findCertificateExtension(const css::uno::Sequence< sal_Int8 > &oid) override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSerialNumber() override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getIssuerUniqueID() override
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
static bool EncodeDistinguishedName(std::u16string_view const rName, CERT_NAME_BLOB &rBlob)
static OUString CompatDNNSS(OUString const &rDN)
bool EqualDistinguishedNames(std::u16string_view const rName1, std::u16string_view const rName2, EqualMode const eMode)
static OUString replaceTagSWithTagST(OUString const &oldDN)
static OUString findOIDDescription(char const *oid)
static std::pair< sal_Int32, sal_Int32 > findTypeInDN(const OUString &rRawString, std::u16string_view sTypeName)
static css::uno::Sequence< sal_Int8 > getThumbprint(const CERT_CONTEXT *pCertContext, DWORD dwPropId)