[med-svn] [Git][med-team/libsecrecy][master] 9 commits: d/watch: change repack suffix from dfsg to ds

Étienne Mollier (@emollier) gitlab at salsa.debian.org
Sat Oct 23 22:57:09 BST 2021



Étienne Mollier pushed to branch master at Debian Med / libsecrecy


Commits:
0a467d49 by Étienne Mollier at 2021-10-23T23:35:58+02:00
d/watch: change repack suffix from dfsg to ds

Files-Excluded are mostly autogenerated files, which are not really
of a concern from a licensing point of view, just technical.

- - - - -
1caa0d3c by Étienne Mollier at 2021-10-23T23:40:03+02:00
routine-update: New upstream version

- - - - -
d9b3411b by Étienne Mollier at 2021-10-23T23:40:04+02:00
New upstream version 0.0.5+ds
- - - - -
df655735 by Étienne Mollier at 2021-10-23T23:40:05+02:00
Update upstream source from tag 'upstream/0.0.5+ds'

Update to upstream version '0.0.5+ds'
with Debian dir 3aa9576c5ee2e16e5760a7e52ca55bd655aafa42
- - - - -
3309bb23 by Étienne Mollier at 2021-10-23T23:40:05+02:00
routine-update: Standards-Version: 4.6.0

- - - - -
59e57ac3 by Étienne Mollier at 2021-10-23T23:44:40+02:00
d/secrecy.manpages: use upstream's manual page

- - - - -
003c68b6 by Étienne Mollier at 2021-10-23T23:47:21+02:00
update changelog

- - - - -
8c8b1895 by Étienne Mollier at 2021-10-23T23:50:46+02:00
d/secrecy.manpages: use suggestion from dh_missing

- - - - -
42e9d55b by Étienne Mollier at 2021-10-23T23:55:16+02:00
routine-update: Ready to upload to unstable

- - - - -


16 changed files:

- ChangeLog
- configure.ac
- debian/changelog
- debian/control
- debian/secrecy.manpages
- debian/watch
- release.sh
- src/Makefile.am
- debian/secrecy.1 → src/apps/secrecy.1
- src/apps/secrecy.cpp
- src/libsecrecy/AESEncryptKey.hpp
- src/libsecrecy/GCMFactoryBase.hpp
- src/libsecrecy/GCMStreamHeader.hpp
- src/libsecrecy/RawKey.hpp
- + src/libsecrecy/SecrecyKeyValueStore.hpp
- − src/libsecrecy/libsecrecy.hpp


Changes:

=====================================
ChangeLog
=====================================
@@ -1,3 +1,24 @@
+libsecrecy (0.0.5-1) unstable; urgency=medium
+
+  * Update email address of Étienne Mollier in the manual page for secrecy
+  * Add manual page for secrecy app kindly provided by Étienne Mollier.
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Tue, 14 Sep 2021 09:29:12 +0200
+
+libsecrecy (0.0.4-1) unstable; urgency=medium
+
+  * Avoid object copying in SecrecyKeyValueStore during map traversal
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Mon, 13 Sep 2021 13:01:43 +0200
+
+libsecrecy (0.0.3-1) unstable; urgency=medium
+
+  * Remove autogenerated file
+  * Avoid object copying in GCMStreamHeader
+  * Check for existence of key directory when listing keys (output empty list instead of failing with an exception)
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Mon, 13 Sep 2021 12:34:49 +0200
+
 libsecrecy (0.0.2-1) unstable; urgency=medium
 
   * Implement key caching infrastructure


=====================================
configure.ac
=====================================
@@ -1,5 +1,5 @@
-AC_INIT(libsecrecy,0.0.2,[germant at miltenyibiotec.de],[libsecrecy],[https://gitlab.com/german.tischler/libsecrecy])
-LIBRARY_VERSION=0:2:0
+AC_INIT(libsecrecy,0.0.5,[germant at miltenyibiotec.de],[libsecrecy],[https://gitlab.com/german.tischler/libsecrecy])
+LIBRARY_VERSION=0:5:0
 AC_MSG_NOTICE([Configuring for source in directory ${srcdir}])
 AC_CANONICAL_SYSTEM
 AC_CANONICAL_HOST


=====================================
debian/changelog
=====================================
@@ -1,10 +1,15 @@
-libsecrecy (0.0.2+dfsg-3) UNRELEASED; urgency=medium
+libsecrecy (0.0.5+ds-1) unstable; urgency=medium
 
   * extend test coverage by testing clang++
   * d/secrecy.1: minor corrections to the manual page
   * d/{control,copyright,secrecy.1}: update packager address
+  * d/watch: change repack suffix from dfsg to ds; files excluded are not of
+    licensing concern per se, just technical.
+  * New upstream version
+  * Standards-Version: 4.6.0 (routine-update)
+  * d/secrecy.manpages: use upstream's manual page
 
- -- Étienne Mollier <emollier at debian.org>  Sat, 10 Jul 2021 18:07:00 +0200
+ -- Étienne Mollier <emollier at debian.org>  Sat, 23 Oct 2021 23:52:25 +0200
 
 libsecrecy (0.0.2+dfsg-2) unstable; urgency=medium
 


=====================================
debian/control
=====================================
@@ -7,7 +7,7 @@ Build-Depends: debhelper-compat (= 13),
                pkg-config,
                libgpgme-dev,
                nettle-dev
-Standards-Version: 4.5.1
+Standards-Version: 4.6.0
 Vcs-Browser: https://salsa.debian.org/med-team/libsecrecy
 Vcs-Git: https://salsa.debian.org/med-team/libsecrecy.git
 Homepage: https://gitlab.com/german.tischler/libsecrecy


=====================================
debian/secrecy.manpages
=====================================
@@ -1 +1 @@
-debian/secrecy.1
+usr/share/man/man1/secrecy.1


=====================================
debian/watch
=====================================
@@ -1,5 +1,5 @@
 version=4
 
-opts="repacksuffix=+dfsg,dversionmangle=auto,repack,compression=xz" \
+opts="repacksuffix=+ds,dversionmangle=auto,repack,compression=xz" \
 https://gitlab.com/german.tischler/libsecrecy/tags?sort=updated_desc \
 .*/archive/.*/libsecrecy at ANY_VERSION@-release-\d+ at ARCHIVE_EXT@


=====================================
release.sh
=====================================
@@ -1,4 +1,5 @@
 #! /bin/bash
+set -e
 
 # update branches
 git checkout experimental


=====================================
src/Makefile.am
=====================================
@@ -11,6 +11,10 @@ lib_LTLIBRARIES = # libsecrecy.la
 
 noinst_HEADERS = # 
 
+MANPAGES = apps/secrecy.1
+man_MANS = ${MANPAGES}
+EXTRA_DIST = ${MANPAGES}
+
 #libsecrecy_la_CPPFLAGS = ${AM_CPPFLAGS} @LIBSECRECYCPPFLAGS@ @ZLIBCPPFLAGS@ @NETTLECPPFLAGS@ @GPGMECPPFLAGS@ @LIBDEFLATECPPFLAGS@
 #libsecrecy_la_CXXFLAGS = @LIBSECRECYCXXFLAGS@ ${AM_CXXFLAGS} @WARNCXXFLAGS@
 #libsecrecy_la_LDFLAGS = @LIBSECRECYLDFLAGS@ -version-info ${LIBRARY_VERSION} @NETTLELDFLAGS@ @GPGMELDFLAGS@ @LIBDEFLATELDFLAGS@
@@ -43,6 +47,7 @@ libsecrecy_include_HEADERS=\
 	libsecrecy/LockedMemory.hpp \
 	libsecrecy/NumToHex.hpp \
 	libsecrecy/RawKey.hpp \
+	libsecrecy/SecrecyKeyValueStore.hpp \
 	libsecrecy/Yarrow.hpp
 	
 EXTRA_PROGRAMS = # 


=====================================
debian/secrecy.1 → src/apps/secrecy.1
=====================================
@@ -41,8 +41,7 @@ and
 The program
 .B secrecy
 accepts several subcommands.
-It is to be noted that,
-currently,
+It is to be noted that, currently,
 .B secrecy
 has no arguments for reading and writing any file.
 One has to rely on the shell capabilities to read and write plain files,
@@ -62,9 +61,7 @@ can currently take the values
 or
 .BR AES256 ,
 .I gpgid
-needs to be a valid id
-(normally an email address)
-present as a secret key in
+needs to be a valid id (normally an email address) present as a secret key in
 .BR gpg (1)'s
 keyring,
 which can be used for securely storing the AES key for use by
@@ -74,9 +71,7 @@ and
 can be chosen as a human readable name for the key created,
 for instance "mykey".
 The program outputs a key hash in the form of a hexadecimal encoded string.
-Either this key hash,
-or the key name given,
-can be provided to the encrypt command of
+Either this key hash or the key name given can to be provided to the encrypt command of
 .B secrecy
 for encrypting files using the newly created key.
 .TP
@@ -143,14 +138,10 @@ key which will be used to locally encrypt the key for storing it in
 database.
 .TP
 .B secrecy listKeys
-List installed keys.
-It prints a tabulation separated table,
-such that the first column contains the key names,
-and the second the respective key hash values.
+List installed keys.  It prints a tabulation separated table such that the first column contains the key names and the second the respective key hash values.
 .TP
 \fBsecrecy setDefaultKey \fIkeyname\fR
-Change the default key.
-The default key is used when an empty
+Change the default key.  The default key is used when an empty
 .I keyname
 is used for running any command accepting a key name,
 with the obvious exceptions of


=====================================
src/apps/secrecy.cpp
=====================================
@@ -50,14 +50,14 @@ void writeKey(std::string const & gpgrecipient, std::string const & keyname)
 	// read back key and check for equality
 	std::string const keyfiledata = libsecrecy::RawKeyBase::readKeyData(hexhash,false /* do not try to resolve name */);
 	std::istringstream keydataistr(keyfiledata);
-	libsecrecy::RawKeyBase::expectMagic(keydataistr);
-	std::string const keycipher = libsecrecy::GCMStreamBase::readString(keydataistr);
-	std::string const rkeyname = libsecrecy::GCMStreamBase::readString(keydataistr);
+
+	std::shared_ptr<libsecrecy::SecrecyKeyValueStore> SKV(libsecrecy::RawKeyBase::loadMetaData(keydataistr));
+	std::string const keycipher = SKV->getStringValue("cipher");
 
 	if ( keycipher != K.getPrefix() )
 		throw std::runtime_error("Decoded key does not match encoded key (wrong cipher)");
 
-	key_type KB(gpgme,keydataistr);
+	key_type KB(gpgme,keydataistr,*SKV);
 
 	bool const eq = (K == KB);
 
@@ -110,12 +110,14 @@ static std::string getExportedKeyMagic()
 }
 
 template<typename key_type>
-void exportKey(std::string const & sgpgid, std::istream & keydataistr, std::string const & keyname)
+void exportKey(std::string const & sgpgid, std::istream & keydataistr, libsecrecy::SecrecyKeyValueStore const & SKV)
 {
 	libsecrecy::GPGMEContext gpgme;
-	key_type KB(gpgme,keydataistr);
+	key_type KB(gpgme,keydataistr,SKV);
 	std::shared_ptr< libsecrecy::LockedMemory<char> > const keyhex = KB.keyToHex();
 
+	std::string const keyname = SKV.getStringValue("keyname");
+
 	std::ostringstream ostr;
 	libsecrecy::GCMStreamBase::writeString(ostr,getExportedKeyMagic());
 	libsecrecy::GCMStreamBase::writeString(ostr,KB.getPrefix());
@@ -180,21 +182,21 @@ int exportKey(char const * progname, int argc, char * argv[])
 	// read back key and check for equality
 	std::string const keyfiledata = libsecrecy::RawKeyBase::readKeyData(skeyname,true /* try to resolve name */);
 	std::istringstream keydataistr(keyfiledata);
-	libsecrecy::RawKeyBase::expectMagic(keydataistr);
-	std::string const keycipher = libsecrecy::GCMStreamBase::readString(keydataistr);
-	std::string const rkeyname = libsecrecy::GCMStreamBase::readString(keydataistr);
+
+	std::shared_ptr<libsecrecy::SecrecyKeyValueStore> SKV(libsecrecy::RawKeyBase::loadMetaData(keydataistr));
+	std::string const keycipher = SKV->getStringValue("cipher");
 
 	if ( keycipher == "AES256" )
 	{
-		exportKey<libsecrecy::AES256EncryptKey>(sgpgid,keydataistr,rkeyname);
+		exportKey<libsecrecy::AES256EncryptKey>(sgpgid,keydataistr,*SKV);
 	}
 	else if ( keycipher == "AES192" )
 	{
-		exportKey<libsecrecy::AES192EncryptKey>(sgpgid,keydataistr,rkeyname);
+		exportKey<libsecrecy::AES192EncryptKey>(sgpgid,keydataistr,*SKV);
 	}
 	else if ( keycipher == "AES128" )
 	{
-		exportKey<libsecrecy::AES128EncryptKey>(sgpgid,keydataistr,rkeyname);
+		exportKey<libsecrecy::AES128EncryptKey>(sgpgid,keydataistr,*SKV);
 	}
 	else
 	{


=====================================
src/libsecrecy/AESEncryptKey.hpp
=====================================
@@ -81,9 +81,9 @@ namespace libsecrecy
 			set_encrypt_key_func(ctx,kptr->get());
 		}
 
-		EncryptKey(libsecrecy::GPGMEContext & context, std::istream & in) : kptr(new raw_key_type), lctx(1), ctx(lctx.get())
+		EncryptKey(libsecrecy::GPGMEContext & context, std::istream & in, SecrecyKeyValueStore const & SKV) : kptr(new raw_key_type), lctx(1), ctx(lctx.get())
 		{
-			kptr->readKey(context,in);
+			kptr->readKey(context,in,SKV);
 			set_encrypt_key_func(ctx,kptr->get());
 		}
 


=====================================
src/libsecrecy/GCMFactoryBase.hpp
=====================================
@@ -41,9 +41,10 @@ namespace libsecrecy
 		{
 			std::string const keyfiledata = RawKeyBase::readKeyData(hexhash,resolve);
 			std::istringstream keydataistr(keyfiledata);
-			RawKeyBase::expectMagic(keydataistr);
-			std::string const scipher = GCMStreamBase::readString(keydataistr);
-			std::string const keyname = GCMStreamBase::readString(keydataistr);
+			std::shared_ptr<libsecrecy::SecrecyKeyValueStore> SKV(libsecrecy::RawKeyBase::loadMetaData(keydataistr));
+			std::string const scipher = SKV->getStringValue("cipher");
+			std::string const skeyname = SKV->getStringValue("keyname");
+
 			std::string keyhex;
 			std::shared_ptr<RawKeyBase> RKB;
 
@@ -52,7 +53,7 @@ namespace libsecrecy
 				typedef AES128EncryptKey key_type;
 				typedef key_type::raw_key_type raw_key_type;
 				std::shared_ptr<RawKeyBase> TRKB(new raw_key_type);
-				dynamic_cast<raw_key_type *>(TRKB.get())->readKey(context,keydataistr);
+				dynamic_cast<raw_key_type *>(TRKB.get())->readKey(context,keydataistr,*SKV);
 				keyhex = dynamic_cast<raw_key_type *>(TRKB.get())->hashToHex();
 				RKB = TRKB;
 			}
@@ -61,7 +62,7 @@ namespace libsecrecy
 				typedef AES192EncryptKey key_type;
 				typedef key_type::raw_key_type raw_key_type;
 				std::shared_ptr<RawKeyBase> TRKB(new raw_key_type);
-				dynamic_cast<raw_key_type *>(TRKB.get())->readKey(context,keydataistr);
+				dynamic_cast<raw_key_type *>(TRKB.get())->readKey(context,keydataistr,*SKV);
 				keyhex = dynamic_cast<raw_key_type *>(TRKB.get())->hashToHex();
 				RKB = TRKB;
 			}
@@ -70,12 +71,12 @@ namespace libsecrecy
 				typedef AES256EncryptKey key_type;
 				typedef key_type::raw_key_type raw_key_type;
 				std::shared_ptr<RawKeyBase> TRKB(new raw_key_type);
-				dynamic_cast<raw_key_type *>(TRKB.get())->readKey(context,keydataistr);
+				dynamic_cast<raw_key_type *>(TRKB.get())->readKey(context,keydataistr,*SKV);
 				keyhex = dynamic_cast<raw_key_type *>(TRKB.get())->hashToHex();
 				RKB = TRKB;
 			}
 
-			return RawKeyObject(RKB,scipher,keyname,keyhex);
+			return RawKeyObject(RKB,scipher,skeyname,keyhex);
 		}
 
 		static RawKeyObject obtainKey(


=====================================
src/libsecrecy/GCMStreamHeader.hpp
=====================================
@@ -26,14 +26,12 @@
 #if ! defined(LIBSECRECY_GCMSTREAMHEADER_HPP)
 #define LIBSECRECY_GCMSTREAMHEADER_HPP
 
-#include <libsecrecy/GCMStreamBase.hpp>
+#include <libsecrecy/SecrecyKeyValueStore.hpp>
 #include <libsecrecy/GCMIV.hpp>
-#include <map>
-#include <vector>
 
 namespace libsecrecy
 {
-	struct GCMStreamHeader : public GCMStreamBase
+	struct GCMStreamHeader : public SecrecyKeyValueStore
 	{
 		std::map<std::string,std::string> M;
 
@@ -46,71 +44,9 @@ namespace libsecrecy
 		{}
 
 		GCMStreamHeader(std::istream & in)
+		: SecrecyKeyValueStore(in,getMagic())
 		{
-			char const * magic = getMagic();
-			while ( *magic )
-			{
-				char const c = getChecked(in);
-				char const e = *(magic++);
-				if ( c != e )
-				{
-					throw std::runtime_error("libsecrecy::GCMStreamHeader: mismatch in file magic");
-				}
-			}
 
-			std::size_t const numfields = readNumber(in);
-
-			for ( std::size_t i = 0; i < numfields; ++i )
-			{
-				std::string const key = readString(in);
-				std::string const value = readString(in);
-				M[key] = value;
-			}
-		}
-
-		std::string toString() const
-		{
-			std::ostringstream ostr;
-			for ( auto const it : M )
-				ostr << "M[" << it.first << "]=" << it.second << "\n";
-			return ostr.str();
-		}
-
-		std::vector<uint8_t> decodeHexField(std::string const & key) const
-		{
-			auto const it = M.find(key);
-
-			if ( it == M.end() )
-				throw std::runtime_error(std::string("libsecrecy::GCMStreamHeader::decodeHexField: key ") + key + " is not present");
-
-			std::string const shex = it->second;
-
-			if ( shex.size() % 2 != 0 )
-			{
-				std::ostringstream ostr;
-				ostr << "libsecrecy::GCMStreamHeader::decodeHexField: value " << shex << " for key " << key << " has uneven length";
-				throw std::runtime_error(ostr.str());
-			}
-
-			std::vector<uint8_t> V;
-			std::string::const_iterator sit = shex.begin();
-			while ( sit != shex.end() )
-			{
-				char const chigh = *(sit++);
-				assert ( sit != shex.end() );
-				char const clow = *(sit++);
-				V.push_back((NumToHex::hexToNum(chigh) << 4) | NumToHex::hexToNum(clow));
-			}
-
-			return V;
-		}
-
-		std::pair < std::shared_ptr<uint8_t[]>, std::size_t > decodeHexFieldAsArray(std::string const & key) const
-		{
-			std::vector<uint8_t> const V(decodeHexField(key));
-			std::shared_ptr<uint8_t[]> ptr(new uint8_t[V.size()]);
-			std::copy(V.begin(),V.end(),ptr.get());
-			return std::make_pair(ptr,V.size());
 		}
 
 		std::pair < std::shared_ptr<uint8_t[]>, std::size_t > getAuthData() const
@@ -130,97 +66,14 @@ namespace libsecrecy
 		{
 			std::size_t r = 0;
 
-			// write magic
-			char const * magic = getMagic();
-			std::size_t const l_magic = strlen(magic);
-			out.write(magic,l_magic);
-			r += l_magic;
-
-			// number of key=value pairs
-			r += writeNumber(out,M.size());
-
-			for ( auto it : M )
-			{
-				r += writeString(out,it.first);
-				r += writeString(out,it.second);
-			}
-
-			if ( ! out )
-			{
-				throw std::runtime_error("libsecrecy::GCMStreamHeader::serialise: failed to write data");
-			}
+			r += SecrecyKeyValueStore::serialise(out,getMagic());
 
 			return r;
 		}
 
 		std::size_t size() const
 		{
-			std::ostringstream ostr;
-			std::size_t const r = serialise(ostr);
-
-			if ( r != ostr.str().size() )
-			{
-				std::ostringstream eostr;
-				eostr << "libsecrecy::GCMStreamHeader::size: mismatch between computed r=" << r << " and actual " << ostr.str().size();
-				throw std::runtime_error(eostr.str());
-			}
-
-			return r;
-		}
-
-		void setStringValue(std::string const & key, std::string const & value)
-		{
-			M[key] = value;
-		}
-
-		template<typename value_type>
-		void setNumericalValue(std::string const & key, value_type const & v)
-		{
-			std::ostringstream ostr;
-			ostr << v;
-			setStringValue(key,ostr.str());
-		}
-
-		std::string getStringValue(std::string const & key) const
-		{
-			auto const it = M.find(key);
-
-			if ( it == M.end() )
-			{
-				std::ostringstream ostr;
-				ostr << "libsecrecy::GCMStreamHeader::getStringValue: field " << key << " is not present";
-				throw std::runtime_error(ostr.str());
-			}
-
-			return it->second;
-		}
-
-		template<typename value_type>
-		value_type getParsedValue(std::string const & key) const
-		{
-			auto const it = M.find(key);
-
-			if ( it == M.end() )
-			{
-				std::ostringstream ostr;
-				ostr << "libsecrecy::GCMStreamHeader::getParsedValue: field " << key << " is not present";
-				throw std::runtime_error(ostr.str());
-			}
-
-			std::istringstream istr(it->second);
-			value_type v;
-			istr >> v;
-
-			if ( istr && istr.peek() == std::istream::traits_type::eof() )
-			{
-				return v;
-			}
-			else
-			{
-				std::ostringstream ostr;
-				ostr << "libsecrecy::GCMStreamHeader::getParsedValue: field " << key << " has unparsable value " << it->second;
-				throw std::runtime_error(ostr.str());
-			}
+			return SecrecyKeyValueStore::size(getMagic());
 		}
 	};
 }


=====================================
src/libsecrecy/RawKey.hpp
=====================================
@@ -29,6 +29,7 @@
 #include <libsecrecy/GPGMEContext.hpp>
 #include <libsecrecy/Yarrow.hpp>
 #include <libsecrecy/GCMStreamBase.hpp>
+#include <libsecrecy/SecrecyKeyValueStore.hpp>
 #include <nettle/aes.h>
 #include <cstdlib>
 #include <filesystem>
@@ -236,17 +237,20 @@ namespace libsecrecy
 		{
 			std::string const keynamedir = getKeyNameDirectory();
 
-			for ( auto const & p : std::filesystem::directory_iterator(keynamedir) )
+			if ( std::filesystem::exists(keynamedir) )
 			{
-				std::filesystem::path const keypath = p.path();
-				std::string hash;
-
-				if ( std::filesystem::exists(keypath) && std::filesystem::is_symlink(keypath) )
+				for ( auto const & p : std::filesystem::directory_iterator(keynamedir) )
 				{
-					hash = static_cast<std::string>(std::filesystem::path(followSymLink(keypath)).filename());
-				}
+					std::filesystem::path const keypath = p.path();
+					std::string hash;
+
+					if ( std::filesystem::exists(keypath) && std::filesystem::is_symlink(keypath) )
+					{
+						hash = static_cast<std::string>(std::filesystem::path(followSymLink(keypath)).filename());
+					}
 
-				out << static_cast<std::string>(keypath.filename()) << "\t" << hash << "\n";
+					out << static_cast<std::string>(keypath.filename()) << "\t" << hash << "\n";
+				}
 			}
 		}
 
@@ -289,6 +293,12 @@ namespace libsecrecy
 			return static_cast<std::string>(curpath);
 		}
 
+		static std::shared_ptr<SecrecyKeyValueStore> loadMetaData(std::istream & in)
+		{
+			std::shared_ptr<SecrecyKeyValueStore> ptr(new SecrecyKeyValueStore(in,getMagic()));
+			return ptr;
+		}
+
 		static std::string readKeyData(std::string hexhash, bool tryname)
 		{
 			if ( !hexhash.size() && tryname )
@@ -391,18 +401,6 @@ namespace libsecrecy
 		{
 			return "LIBSECRECY_KEY";
 		}
-
-		static void expectMagic(std::istream & in)
-		{
-			std::string const magic = GCMStreamBase::readString(in);
-
-			if ( magic != getMagic() )
-			{
-				std::ostringstream estr;
-				estr << "libsecrecy::RawKey::expectMagic: mismatch in file identifier";
-				throw std::runtime_error(estr.str());
-			}
-		}
 	};
 
 	struct RawKeyObject
@@ -619,13 +617,12 @@ namespace libsecrecy
 
 			std::ostringstream sstr;
 
-			GCMStreamBase::writeString(sstr,getMagic());
-			// write prefix / cipher
-			GCMStreamBase::writeString(sstr,cipher);
-			// write name value
-			GCMStreamBase::writeString(sstr,keyname);
-			// write hash value
-			GCMStreamBase::writeString(sstr,hashToHex());
+			SecrecyKeyValueStore SKV;
+			SKV.setStringValue("cipher",cipher);
+			SKV.setStringValue("keyname",keyname);
+			SKV.setStringValue("hash",hashToHex());
+			SKV.serialise(sstr,getMagic());
+
 			// write encrypted key
 			context.encrypt(
 				reinterpret_cast<char const *>(L.begin()),
@@ -681,9 +678,9 @@ namespace libsecrecy
 			std::filesystem::current_path(lcwd);
 		}
 
-		void readKey(libsecrecy::GPGMEContext & context, std::istream & in)
+		void readKey(libsecrecy::GPGMEContext & context, std::istream & in, SecrecyKeyValueStore const & SKV)
 		{
-			std::string const shexhash = GCMStreamBase::readString(in);
+			std::string const shexhash = SKV.getStringValue("hash");
 
 			if ( shexhash.size() != 2*digestsize )
 			{


=====================================
src/libsecrecy/SecrecyKeyValueStore.hpp
=====================================
@@ -0,0 +1,208 @@
+/**
+ * Copyright 2020 German Tischler-Höhle
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ **/
+#if ! defined(LIBSECRECY_SECRECYKEYVALUESTORE_HPP)
+#define LIBSECRECY_SECRECYKEYVALUESTORE_HPP
+
+#include <libsecrecy/GCMStreamBase.hpp>
+#include <map>
+#include <vector>
+
+namespace libsecrecy
+{
+	struct SecrecyKeyValueStore : public GCMStreamBase
+	{
+		std::map<std::string,std::string> M;
+
+		SecrecyKeyValueStore()
+		{}
+		SecrecyKeyValueStore(std::istream & in, std::string const & smagic)
+		{
+			char const * magic = smagic.c_str();
+
+			while ( *magic )
+			{
+				char const c = getChecked(in);
+				char const e = *(magic++);
+				if ( c != e )
+				{
+					throw std::runtime_error("libsecrecy::SecrecyKeyValueStore: mismatch in file magic");
+				}
+			}
+
+			std::size_t const numfields = readNumber(in);
+
+			for ( std::size_t i = 0; i < numfields; ++i )
+			{
+				std::string const key = readString(in);
+				std::string const value = readString(in);
+				M[key] = value;
+			}
+		}
+
+		std::string toString() const
+		{
+			std::ostringstream ostr;
+			for ( auto const & it : M )
+				ostr << "M[" << it.first << "]=" << it.second << "\n";
+			return ostr.str();
+		}
+
+		std::vector<uint8_t> decodeHexField(std::string const & key) const
+		{
+			auto const it = M.find(key);
+
+			if ( it == M.end() )
+				throw std::runtime_error(std::string("libsecrecy::SecrecyKeyValueStore::decodeHexField: key ") + key + " is not present");
+
+			std::string const shex = it->second;
+
+			if ( shex.size() % 2 != 0 )
+			{
+				std::ostringstream ostr;
+				ostr << "libsecrecy::SecrecyKeyValueStore::decodeHexField: value " << shex << " for key " << key << " has uneven length";
+				throw std::runtime_error(ostr.str());
+			}
+
+			std::vector<uint8_t> V;
+			std::string::const_iterator sit = shex.begin();
+			while ( sit != shex.end() )
+			{
+				char const chigh = *(sit++);
+				assert ( sit != shex.end() );
+				char const clow = *(sit++);
+				V.push_back((NumToHex::hexToNum(chigh) << 4) | NumToHex::hexToNum(clow));
+			}
+
+			return V;
+		}
+
+		std::pair < std::shared_ptr<uint8_t[]>, std::size_t > decodeHexFieldAsArray(std::string const & key) const
+		{
+			std::vector<uint8_t> const V(decodeHexField(key));
+			std::shared_ptr<uint8_t[]> ptr(new uint8_t[V.size()]);
+			std::copy(V.begin(),V.end(),ptr.get());
+			return std::make_pair(ptr,V.size());
+		}
+
+		std::size_t serialise(std::ostream & out, std::string const & smagic) const
+		{
+			std::size_t r = 0;
+
+			// write magic
+			char const * magic = smagic.c_str();
+			std::size_t const l_magic = strlen(magic);
+			out.write(magic,l_magic);
+			r += l_magic;
+
+			// number of key=value pairs
+			r += writeNumber(out,M.size());
+
+			for ( auto it : M )
+			{
+				r += writeString(out,it.first);
+				r += writeString(out,it.second);
+			}
+
+			if ( ! out )
+			{
+				throw std::runtime_error("libsecrecy::SecrecyKeyValueStore::serialise: failed to write data");
+			}
+
+			return r;
+		}
+
+		std::size_t size(std::string const & smagic) const
+		{
+			std::ostringstream ostr;
+			std::size_t const r = serialise(ostr,smagic);
+
+			if ( r != ostr.str().size() )
+			{
+				std::ostringstream eostr;
+				eostr << "libsecrecy::SecrecyKeyValueStore::size: mismatch between computed r=" << r << " and actual " << ostr.str().size();
+				throw std::runtime_error(eostr.str());
+			}
+
+			return r;
+		}
+
+		void setStringValue(std::string const & key, std::string const & value)
+		{
+			M[key] = value;
+		}
+
+		template<typename value_type>
+		void setNumericalValue(std::string const & key, value_type const & v)
+		{
+			std::ostringstream ostr;
+			ostr << v;
+			setStringValue(key,ostr.str());
+		}
+
+		std::string getStringValue(std::string const & key) const
+		{
+			auto const it = M.find(key);
+
+			if ( it == M.end() )
+			{
+				std::ostringstream ostr;
+				ostr << "libsecrecy::SecrecyKeyValueStore::getStringValue: field " << key << " is not present";
+				throw std::runtime_error(ostr.str());
+			}
+
+			return it->second;
+		}
+
+		template<typename value_type>
+		value_type getParsedValue(std::string const & key) const
+		{
+			auto const it = M.find(key);
+
+			if ( it == M.end() )
+			{
+				std::ostringstream ostr;
+				ostr << "libsecrecy::SecrecyKeyValueStore::getParsedValue: field " << key << " is not present";
+				throw std::runtime_error(ostr.str());
+			}
+
+			std::istringstream istr(it->second);
+			value_type v;
+			istr >> v;
+
+			if ( istr && istr.peek() == std::istream::traits_type::eof() )
+			{
+				return v;
+			}
+			else
+			{
+				std::ostringstream ostr;
+				ostr << "libsecrecy::SecrecyKeyValueStore::getParsedValue: field " << key << " has unparsable value " << it->second;
+				throw std::runtime_error(ostr.str());
+			}
+		}
+	};
+}
+#endif


=====================================
src/libsecrecy/libsecrecy.hpp deleted
=====================================
@@ -1,69 +0,0 @@
-/**
- * Copyright 2020 German Tischler-Höhle
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **/
-
-/**
- * headers
- **/
-
-/**
- * functions
- **/
-
-/**
- * functions blocks
- **/
-
-/**
- * compiler features
- **/
-
-/**
- * third party libraries
- **/
-
-/**
- * capabilities in third party libraries
- **/
-
-/**
- * flag constants
- **/
-
-/**
- * numeric constants
- **/
-
-/**
- * compilation flags
- **/
-
-/**
- * enable/disable feature flags
- **/
-
-/**
- * info flags
- **/



View it on GitLab: https://salsa.debian.org/med-team/libsecrecy/-/compare/d1f91dc6b5e8bdd5a2d87f560c7484e74ab9ed3f...42e9d55b8aba7be7661ee156457d3f985231e9ab

-- 
View it on GitLab: https://salsa.debian.org/med-team/libsecrecy/-/compare/d1f91dc6b5e8bdd5a2d87f560c7484e74ab9ed3f...42e9d55b8aba7be7661ee156457d3f985231e9ab
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20211023/bfd1a518/attachment-0001.htm>


More information about the debian-med-commit mailing list