aboutsummaryrefslogtreecommitdiff
path: root/bpkg/manifest.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-04-29 10:07:03 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-05-04 20:37:44 +0300
commit057a5d5d435d53166d1b8751748a9ba0a317bee3 (patch)
tree6770b5ba1566c95e79ad73e845ac4a04c145cbec /bpkg/manifest.cxx
parentd61e9338c8eda118c5f2afd93827be4a84bdc36a (diff)
Add signature_manifest class
Diffstat (limited to 'bpkg/manifest.cxx')
-rw-r--r--bpkg/manifest.cxx96
1 files changed, 95 insertions, 1 deletions
diff --git a/bpkg/manifest.cxx b/bpkg/manifest.cxx
index b94c2c6..ff1c88f 100644
--- a/bpkg/manifest.cxx
+++ b/bpkg/manifest.cxx
@@ -18,6 +18,7 @@
#include <stdexcept> // invalid_argument
#include <butl/path>
+#include <butl/base64>
#include <bpkg/manifest-parser>
#include <bpkg/manifest-serializer>
@@ -1197,7 +1198,7 @@ namespace bpkg
{
// @@ Should we check that all non-optional values are specified ?
// @@ Should we check that values are valid: name is not empty, version
- // release is not empty, sha256sum is a proper string, ...
+ // release is not empty, sha256sum is a proper string, ...?
// @@ Currently we don't know if we are serializing the individual package
// manifest or the package list manifest, so can't ensure all values
// allowed in the current context (location, sha256sum, *-file values).
@@ -2072,4 +2073,97 @@ namespace bpkg
s.next ("", ""); // End of stream.
}
+
+ // signature_manifest
+ //
+ signature_manifest::
+ signature_manifest (parser& p, bool iu)
+ : signature_manifest (p, p.next (), iu) // Delegate
+ {
+ // Make sure this is the end.
+ //
+ name_value nv (p.next ());
+ if (!nv.empty ())
+ throw parsing (p.name (), nv.name_line, nv.name_column,
+ "single signature manifest expected");
+ }
+
+ signature_manifest::
+ signature_manifest (parser& p, name_value nv, bool iu)
+ {
+ auto bad_name ([&p, &nv](const string& d) {
+ throw parsing (p.name (), nv.name_line, nv.name_column, d);});
+
+ auto bad_value ([&p, &nv](const string& d) {
+ throw parsing (p.name (), nv.value_line, nv.value_column, d);});
+
+ // Make sure this is the start and we support the version.
+ //
+ if (!nv.name.empty ())
+ bad_name ("start of signature manifest expected");
+
+ if (nv.value != "1")
+ bad_value ("unsupported format version");
+
+ for (nv = p.next (); !nv.empty (); nv = p.next ())
+ {
+ string& n (nv.name);
+ string& v (nv.value);
+
+ if (n == "sha256sum")
+ {
+ if (!sha256sum.empty ())
+ bad_name ("sha256sum redefinition");
+
+ if (v.empty ())
+ bad_value ("empty sha256sum");
+
+ if (!valid_sha256 (v))
+ bad_value ("invalid sha256sum");
+
+ sha256sum = move (v);
+ }
+ else if (n == "signature")
+ {
+ if (!signature.empty ())
+ bad_name ("signature redefinition");
+
+ if (v.empty ())
+ bad_value ("empty signature");
+
+ // Try to base64-decode as a sanity check.
+ //
+ try
+ {
+ signature = base64_decode (v);
+ }
+ catch (const invalid_argument&)
+ {
+ bad_value ("invalid signature");
+ }
+ }
+ else if (!iu)
+ bad_name ("unknown name '" + n + "' in signature manifest");
+ }
+
+ // Verify all non-optional values were specified.
+ //
+ if (sha256sum.empty ())
+ bad_value ("no sha256sum specified");
+ else if (signature.empty ())
+ bad_value ("no signature specified");
+ }
+
+ void signature_manifest::
+ serialize (serializer& s) const
+ {
+ // @@ Should we check that values are valid ?
+ //
+ s.next ("", "1"); // Start of manifest.
+
+ s.next ("sha256sum", sha256sum);
+ s.next ("signature", base64_encode (signature));
+
+ s.next ("", ""); // End of manifest.
+ }
}