Merge "[public] Make marshal and parsing functions methods"
diff --git a/build.rs b/build.rs
index 6662e83..1af1bd1 100644
--- a/build.rs
+++ b/build.rs
@@ -49,6 +49,12 @@
     let built_with = built_with(&abs_build_dir_1);
     let have_ninja = have_ninja();
     let build = |build_dir, flags: &[&str]| {
+        // Add CMAKE_POSITION_INDEPENDENT_CODE=1 to the list of CMake variables.
+        // This causes compilation with -fPIC, which is required on some
+        // platforms. This was added to address
+        // https://github.com/google/mundane/issues/3
+        let mut flags = flags.to_vec();
+        flags.push("-DCMAKE_POSITION_INDEPENDENT_CODE=1");
         fn with_ninja<'a, 'b>(flags: &'a [&'b str]) -> Vec<&'b str> {
             let mut flags = flags.to_vec();
             flags.push("-GNinja");
@@ -63,19 +69,19 @@
         // introducing the complexity necessary to support that use case.
         match built_with {
             Some(BuildSystem::Ninja) => {
-                run("cmake", &with_ninja(flags));
+                run("cmake", &with_ninja(&flags));
                 run("ninja", &["crypto"]);
             }
             Some(BuildSystem::Make) => {
-                run("cmake", flags);
+                run("cmake", &flags);
                 run("make", &["crypto"]);
             }
             None => {
                 if have_ninja {
-                    run("cmake", &with_ninja(flags));
+                    run("cmake", &with_ninja(&flags));
                     run("ninja", &["crypto"]);
                 } else {
-                    run("cmake", flags);
+                    run("cmake", &flags);
                     run("make", &["crypto"]);
                 }
             }
diff --git a/src/boringssl/mod.rs b/src/boringssl/mod.rs
index b53e089..56d280d 100644
--- a/src/boringssl/mod.rs
+++ b/src/boringssl/mod.rs
@@ -222,9 +222,7 @@
 
     /// The `EC_KEY_get0_group` function.
     #[must_use]
-    // TODO(joshlf): Replace with #[allow(clippy::needless_lifetimes)] once the
-    // tool_lints feature is stable
-    #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_lifetimes))] // to be more explicit
+    #[allow(clippy::needless_lifetimes)] // to be more explicit
     pub fn ec_key_get0_group<'a>(&'a self) -> Result<CRef<'a, EC_GROUP>, BoringError> {
         // get0 doesn't increment the refcount; the lifetimes ensure that the
         // returned CRef can't outlive self
diff --git a/src/boringssl/raw.rs b/src/boringssl/raw.rs
index 4d7ee63..d8b212b 100644
--- a/src/boringssl/raw.rs
+++ b/src/boringssl/raw.rs
@@ -257,9 +257,7 @@
 }
 
 #[allow(non_snake_case)]
-// TODO(joshlf): Replace with #[allow(clippy::too_many_arguments)] once the
-// tool_lints feature is stable
-#[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
+#[allow(clippy::too_many_arguments)]
 #[must_use]
 pub unsafe fn EVP_PBE_scrypt(
     password: *const c_char,
@@ -292,9 +290,7 @@
 
 #[cfg(feature = "kdf")]
 #[allow(non_snake_case)]
-// TODO(joshlf): Replace with #[allow(clippy::too_many_arguments)] once the
-// tool_lints feature is stable
-#[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
+#[allow(clippy::too_many_arguments)]
 #[must_use]
 pub unsafe fn PKCS5_PBKDF2_HMAC(
     password: *const c_char,
diff --git a/src/public/mod.rs b/src/public/mod.rs
index 2f225a2..5233bb0 100644
--- a/src/public/mod.rs
+++ b/src/public/mod.rs
@@ -18,6 +18,16 @@
 pub trait PublicKey: Sealed + Sized {
     /// The type of the private component.
     type Private: PrivateKey<Public = Self>;
+
+    /// Verifies a message with this public key.
+    ///
+    /// `verify` verifies that a message was signed by the private key
+    /// corresponding to this public key. It is equivalent to
+    /// `signature.verify(self, message)`.
+    #[must_use]
+    fn verify<S: Signature<PrivateKey = Self::Private>>(&self, message: &[u8], signature: &S) -> bool {
+        signature.verify(self, message)
+    }
 }
 
 /// The private component of a public/private key pair.
@@ -28,6 +38,15 @@
     /// Gets the public key corresponding to this private key.
     #[must_use]
     fn public(&self) -> Self::Public;
+
+    /// Signs a message with this private key.
+    ///
+    /// `sign` signs a message with this key using the signature scheme `S`. It
+    /// is equivalent to `S::sign(self, message)`.
+    #[must_use]
+    fn sign<S: Signature<PrivateKey = Self>>(&self, message: &[u8]) -> Result<S, Error> {
+        S::sign(self, message)
+    }
 }
 
 /// A public key which can be encoded as a DER object.
@@ -215,8 +234,16 @@
         ) -> S {
             let sig = S::sign(key, message).unwrap();
             assert!(sig.verify(&key.public(), message));
+            // Make sure the PrivateKey::sign and PublicKey::verify convenience
+            // functions also work.
+            let sig = key.sign::<S>(message).unwrap();
+            assert!(key.public().verify(message, &sig));
             let sig2 = S::sign(&key, bytes_from_sig(&sig)).unwrap();
             assert!(!sig2.verify(&key.public(), message));
+            // Make sure the PrivateKey::sign and PublicKey::verify convenience
+            // functions also work.
+            let sig2 = key.sign::<S>(bytes_from_sig(&sig)).unwrap();
+            assert!(!key.public().verify(message, &sig2));
             sig_from_bytes(bytes_from_sig(&sig))
         }