summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorSamuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>2018-11-09 16:42:16 +0100
committerSamuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>2018-11-12 14:52:09 +0100
commit9c5d3e5c59a9d0ffcb5fd99f5d4c98b0f6b5560e (patch)
tree21e1f2cd8b791414812a484f7df8691ac4e2e594 /comphelper
parent3d885f20269dd4b7485fbe09c70014646e799366 (diff)
tdf#118581 Correctly display issuer name in signature line
Move the xmlsec helper methods to comphelper so that we can use them in cui Change-Id: If9b10cfff5f5abd6b16e48f043af7959edbb1142 Reviewed-on: https://gerrit.libreoffice.org/63198 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/Library_comphelper.mk1
-rw-r--r--comphelper/source/misc/xmlsechelper.cxx335
2 files changed, 336 insertions, 0 deletions
diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 04b333db9af9..a5275f971be4 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -143,6 +143,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
comphelper/source/misc/types \
comphelper/source/misc/weak \
comphelper/source/misc/weakeventlistener \
+ comphelper/source/misc/xmlsechelper \
comphelper/source/officeinstdir/officeinstallationdirectories \
comphelper/source/processfactory/processfactory \
comphelper/source/property/ChainablePropertySet \
diff --git a/comphelper/source/misc/xmlsechelper.cxx b/comphelper/source/misc/xmlsechelper.cxx
new file mode 100644
index 000000000000..84ccd203092f
--- /dev/null
+++ b/comphelper/source/misc/xmlsechelper.cxx
@@ -0,0 +1,335 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <comphelper/xmlsechelper.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/fixed.hxx>
+#include <svl/solar.hrc>
+#include <unotools/syslocale.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustrbuf.h>
+#include <vector>
+
+using namespace std;
+
+namespace comphelper
+{
+namespace xmlsec
+{
+ OUString GetCertificateKind( const css::security::CertificateKind &rKind )
+ {
+ switch (rKind)
+ {
+ case css::security::CertificateKind_X509:
+ return OUString("X.509");
+ case css::security::CertificateKind_OPENPGP:
+ return OUString("OpenPGP");
+ default:
+ return OUString();
+ }
+ }
+
+ /*
+ Creates two strings based on the distinguished name which are displayed in the
+ certificate details view. The first string contains only the values of the attribute
+ and values pairs, which are separated by commas. All escape characters ('"') are
+ removed.
+ The second string is for the details view at the bottom. It shows the attribute/value
+ pairs on different lines. All escape characters ('"') are removed.
+ */
+ pair< OUString, OUString> GetDNForCertDetailsView( const OUString & rRawString)
+ {
+ vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(rRawString);
+ OUStringBuffer s1, s2;
+ for (auto i = vecAttrValueOfDN.cbegin(); i < vecAttrValueOfDN.cend(); ++i)
+ {
+ if (i != vecAttrValueOfDN.cbegin())
+ {
+ s1.append(',');
+ s2.append('\n');
+ }
+ s1.append(i->second);
+ s2.append(i->first).append(" = ").append(i->second);
+ }
+ return make_pair(s1.makeStringAndClear(), s2.makeStringAndClear());
+ }
+
+/*
+ Whenever the attribute value contains special characters, such as '"' or ',' (without '')
+ then the value will be enclosed in double quotes by the respective Windows or NSS function
+ which we use to retrieve, for example, the subject name. If double quotes appear in the value then
+ they are escaped with a double quote. This function removes the escape characters.
+*/
+#ifdef _WIN32
+vector< pair< OUString, OUString> > parseDN(const OUString& rRawString)
+{
+ vector< pair<OUString, OUString> > retVal;
+ bool bInEscape = false;
+ bool bInValue = false;
+ bool bInType = true;
+ sal_Int32 nTypeNameStart = 0;
+ OUString sType;
+ OUStringBuffer sbufValue;
+ sal_Int32 length = rRawString.getLength();
+
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ sal_Unicode c = rRawString[i];
+
+ if (c == '=')
+ {
+ if (! bInValue)
+ {
+ sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
+ sType = sType.trim();
+ bInType = false;
+ }
+ else
+ {
+ sbufValue.append(c);
+ }
+ }
+ else if (c == '"')
+ {
+ if (!bInEscape)
+ {
+ //If this is the quote is the first of the couple which enclose the
+ //whole value, because the value contains special characters
+ //then we just drop it. That is, this character must be followed by
+ //a character which is not '"'.
+ if ( i + 1 < length && rRawString[i+1] == '"')
+ bInEscape = true;
+ else
+ bInValue = !bInValue; //value is enclosed in " "
+ }
+ else
+ {
+ //This quote is escaped by a preceding quote and therefore is
+ //part of the value
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ else if (c == ',' || c == '+')
+ {
+ //The comma separate the attribute value pairs.
+ //If the comma is not part of a value (the value would then be enclosed in '"'),
+ //then we have reached the end of the value
+ if (!bInValue)
+ {
+ OSL_ASSERT(!sType.isEmpty());
+ retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
+ sType.clear();
+ //The next char is the start of the new type
+ nTypeNameStart = i + 1;
+ bInType = true;
+ }
+ else
+ {
+ //The whole string is enclosed because it contains special characters.
+ //The enclosing '"' are not part of certificate but will be added by
+ //the function (Windows or NSS) which retrieves DN
+ sbufValue.append(c);
+ }
+ }
+ else
+ {
+ if (!bInType)
+ sbufValue.append(c);
+ }
+ }
+ if (sbufValue.getLength())
+ {
+ OSL_ASSERT(!sType.isEmpty());
+ retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
+ }
+ return retVal;
+ }
+#else
+vector< pair< OUString, OUString> > parseDN(const OUString& rRawString)
+ {
+ vector< pair<OUString, OUString> > retVal;
+ //bInEscape == true means that the preceding character is an escape character
+ bool bInEscape = false;
+ bool bInValue = false;
+ bool bInType = true;
+ sal_Int32 nTypeNameStart = 0;
+ OUString sType;
+ OUStringBuffer sbufValue;
+ sal_Int32 length = rRawString.getLength();
+
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ sal_Unicode c = rRawString[i];
+
+ if (c == '=')
+ {
+ if (! bInValue)
+ {
+ sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
+ sType = sType.trim();
+ bInType = false;
+ }
+ else
+ {
+ sbufValue.append(c);
+ }
+ }
+ else if (c == '\\')
+ {
+ if (!bInEscape)
+ {
+ bInEscape = true;
+ }
+ else
+ { // bInEscape is true
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ else if (c == '"')
+ {
+ //an unescaped '"' is either at the beginning or end of the value
+ if (!bInEscape)
+ {
+ if ( !bInValue)
+ bInValue = true;
+ else if (bInValue)
+ bInValue = false;
+ }
+ else
+ {
+ //This quote is escaped by a preceding quote and therefore is
+ //part of the value
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ else if (c == ',' || c == '+')
+ {
+ //The comma separate the attribute value pairs.
+ //If the comma is not part of a value (the value would then be enclosed in '"'),
+ //then we have reached the end of the value
+ if (!bInValue)
+ {
+ OSL_ASSERT(!sType.isEmpty());
+ retVal.emplace_back(sType, sbufValue.makeStringAndClear());
+ sType.clear();
+ //The next char is the start of the new type
+ nTypeNameStart = i + 1;
+ bInType = true;
+ }
+ else
+ {
+ //The whole string is enclosed because it contains special characters.
+ //The enclosing '"' are not part of certificate but will be added by
+ //the function (Windows or NSS) which retrieves DN
+ sbufValue.append(c);
+ }
+ }
+ else
+ {
+ if (!bInType)
+ {
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ }
+ if (!sbufValue.isEmpty())
+ {
+ OSL_ASSERT(!sType.isEmpty());
+ retVal.emplace_back(sType, sbufValue.makeStringAndClear());
+ }
+ return retVal;
+ }
+
+#endif
+
+ OUString GetContentPart( const OUString& _rRawString )
+ {
+ char const * aIDs[] = { "CN", "OU", "O", "E", nullptr };
+ bool shouldBeParsed = false;
+ int i = 0;
+ while ( aIDs[i] )
+ {
+ if (_rRawString.startsWith(OUString::createFromAscii(aIDs[i++])))
+ {
+ shouldBeParsed = true;
+ break;
+ }
+ }
+
+ if (!shouldBeParsed)
+ return _rRawString;
+
+ OUString retVal;
+ i = 0;
+ vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(_rRawString);
+ while ( aIDs[i] )
+ {
+ OUString sPartId = OUString::createFromAscii( aIDs[i++] );
+ auto idn = std::find_if(vecAttrValueOfDN.cbegin(), vecAttrValueOfDN.cend(),
+ [&sPartId](const pair< OUString, OUString >& dn) { return dn.first == sPartId; });
+ if (idn != vecAttrValueOfDN.cend())
+ retVal = idn->second;
+ if (!retVal.isEmpty())
+ break;
+ }
+ return retVal;
+ }
+
+ OUString GetHexString( const css::uno::Sequence< sal_Int8 >& _rSeq, const char* _pSep, sal_uInt16 _nLineBreak )
+ {
+ const sal_Int8* pSerNumSeq = _rSeq.getConstArray();
+ int nCnt = _rSeq.getLength();
+ OUStringBuffer aStr;
+ const char pHexDigs[ 17 ] = "0123456789ABCDEF";
+ char pBuffer[ 3 ] = " ";
+ sal_uInt8 nNum;
+ sal_uInt16 nBreakStart = _nLineBreak? _nLineBreak : 1;
+ sal_uInt16 nBreak = nBreakStart;
+ for( int i = 0 ; i < nCnt ; ++i )
+ {
+ nNum = sal_uInt8( pSerNumSeq[ i ] );
+
+ // exchange the buffer[0] and buffer[1], which make it consistent with Mozilla and Windows
+ pBuffer[ 1 ] = pHexDigs[ nNum & 0x0F ];
+ nNum >>= 4;
+ pBuffer[ 0 ] = pHexDigs[ nNum ];
+ aStr.appendAscii( pBuffer );
+
+ --nBreak;
+ if( nBreak )
+ aStr.appendAscii( _pSep );
+ else
+ {
+ nBreak = nBreakStart;
+ aStr.append( '\n' );
+ }
+ }
+
+ return aStr.makeStringAndClear();
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */