public void VerifyNulls() { Exception ex = Record.Exception(() => PGPSignature.Verify(default(string), null)); Assert.NotNull(ex); Assert.IsType <PgpDataValidationException>(ex); }
/// <summary> /// Digitally signs the specified manifest, adds the signature to the manifest, and returns it. /// </summary> /// <param name="manifest">The manifest to sign.</param> /// <param name="privateKey">The PGP private key with which to sign the file.</param> /// <param name="passphrase">The passphrase for the PGP private key.</param> /// <param name="keybaseUsername"> /// The Keybase.io username of the account hosting the PGP public key used for digest verification. /// </param> /// <returns>The signed manifest.</returns> private PackageManifest SignManifest(PackageManifest manifest, string privateKey, string passphrase, string keybaseUsername) { Info("Digitally signing manifest..."); // insert a signature into the manifest. the signer must be included in the hash to prevent tampering. PackageManifestSignature signature = new PackageManifestSignature(); signature.Issuer = PackagingConstants.KeyIssuer; signature.Subject = keybaseUsername; manifest.Signature = signature; Verbose("Creating SHA512 hash of serialized manifest..."); string manifestHash = Utility.ComputeSHA512Hash(manifest.ToJson()); Verbose($"Hash computed successfully: {manifestHash}."); byte[] manifestBytes = Encoding.ASCII.GetBytes(manifest.ToJson()); Verbose("Creating digest..."); byte[] digestBytes = PGPSignature.Sign(manifestBytes, privateKey, passphrase); Verbose("Digest created successfully."); Verbose("Adding signature to manifest..."); manifest.Signature.Digest = Encoding.ASCII.GetString(digestBytes); Success("Manifest signed successfully."); return(manifest); }
public void SignNullPassword() { Exception ex = Record.Exception(() => PGPSignature.Sign(new byte[0], privateKey, null)); Assert.NotNull(ex); Assert.IsType <NullReferenceException>(ex); }
public void VerifyBadSignature() { Exception ex = Record.Exception(() => PGPSignature.Verify(new byte[0], publicKey)); Assert.NotNull(ex); Assert.IsType <PgpDataValidationException>(ex); }
public void SignNullKey() { Exception ex = Record.Exception(() => PGPSignature.Sign(new byte[0], null, password)); Assert.NotNull(ex); Assert.IsType <PgpKeyValidationException>(ex); }
public void SignNullBytes() { Exception ex = Record.Exception(() => PGPSignature.Sign(null, privateKey, password)); Assert.NotNull(ex); Assert.IsType <NullReferenceException>(ex); }
public void SignBadPassword() { Exception ex = Record.Exception(() => PGPSignature.Sign(new byte[0], privateKey, string.Empty)); Assert.NotNull(ex); Assert.IsType <PgpException>(ex); }
/// <summary> /// Adds a Trust to the <see cref="PackageManifest"/> within the specified package using the PGP private key in the /// specified file and the specified passphrase. /// </summary> /// <param name="packageFile">The Package for which the Trust is to be added.</param> /// <param name="privateKey">The ASCII armored PGP private key.</param> /// <param name="passphrase">The passphrase for the specified PGP private key.</param> public void TrustPackage(string packageFile, string privateKey, string passphrase) { ArgumentValidator.ValidatePackageFileArgumentForWriting(packageFile, true); ArgumentValidator.ValidatePrivateKeyArguments(privateKey, passphrase); Info($"Adding Trust to Package '{Path.GetFileName(packageFile)}'..."); Exception deferredException = default(Exception); string tempDirectory = Path.Combine(Path.GetTempPath(), GetType().Namespace.Split('.')[0], Guid.NewGuid().ToString()); try { PackageManifest manifest = new ManifestExtractor().ExtractManifest(packageFile); Verbose("Checking (but not validating) Digest..."); if (manifest.Signature == default(PackageManifestSignature) || string.IsNullOrEmpty(manifest.Signature.Digest)) { throw new InvalidOperationException("The Package is not signed and can not be trusted."); } Verbose("Digest OK."); Verbose("Signing Digest to create the Trust..."); byte[] digestBytes = Encoding.ASCII.GetBytes(manifest.Signature.Digest); byte[] trustBytes = PGPSignature.Sign(digestBytes, privateKey, passphrase); string trust = Encoding.ASCII.GetString(trustBytes); Verbose("Trust created successfully."); manifest.Signature.Trust = trust; UpdatePackageManifest(packageFile, manifest, tempDirectory); } catch (Exception ex) { deferredException = ex; } finally { Verbose("Deleting temporary files..."); if (Directory.Exists(tempDirectory)) { Directory.Delete(tempDirectory, true); } Verbose("Temporary files deleted successfully."); if (deferredException != default(Exception)) { throw deferredException; } } Success($"Trust added to Package '{Path.GetFileName(packageFile)}' successfully."); }
public void Sign() { string text = "hello world!"; byte[] bytes = Encoding.ASCII.GetBytes(text); byte[] signatureBytes = PGPSignature.Sign(bytes, privateKey, password); string signature = Encoding.ASCII.GetString(signatureBytes); Assert.NotNull(signature); Assert.NotEqual(string.Empty, signature); }
/// <summary> /// Verifies the Digest contained in the specified Manifest using the specified PGP Public Key. /// </summary> /// <param name="manifest">The Manifest for which the Digest is to be verified.</param> /// <param name="publicKey">The PGP Public Key with which to verify the Digest.</param> /// <exception cref="InvalidDataException"> /// Thrown when an error is encountered verifying the Digest, or when the Manifest contents do not match the verified Digest. /// </exception> private void VerifyDigest(PackageManifest manifest, string publicKey) { string verifiedDigest = string.Empty; if (!string.IsNullOrEmpty(manifest.Signature.Digest)) { Verbose("Verifying the Manifest Digest..."); byte[] digestBytes = Encoding.ASCII.GetBytes(manifest.Signature.Digest); byte[] verifiedDigestBytes; try { verifiedDigestBytes = PGPSignature.Verify(digestBytes, publicKey); } catch (Exception ex) { throw new InvalidDataException($"an Exception was thrown while verifying the Digest: {ex.GetType().Name}: {ex.Message}", ex); } verifiedDigest = Encoding.ASCII.GetString(verifiedDigestBytes); // deserialize the verified manifest to work around text formatting differences on various platforms PackageManifest verifiedManifest; try { verifiedManifest = JsonConvert.DeserializeObject <PackageManifest>(verifiedDigest); } catch (Exception ex) { throw new InvalidDataException($"an Exception was thrown while deserializing the Digest: {ex.GetType().Name}: {ex.Message}", ex); } // remove the digest and trust from the manifest, then serialize it and compare it to the verified digest. manifest.Signature.Digest = default(string); manifest.Signature.Trust = default(string); // if the scrubbed manifest and verified digest don't match, something was tampered with. if (manifest.ToJson() != verifiedManifest.ToJson()) { throw new InvalidDataException("the Manifest Digest is not valid; the verified Digest does not match the Manifest."); } Verbose("Digest verified successfully."); } else { throw new InvalidDataException("the Manifest Digest is null or empty."); } }
public void VerifyWrongKey() { string text = "hello world!"; byte[] signature = GetSignature(text); Assert.NotNull(signature); Assert.NotEqual(0, signature.Length); Exception ex = Record.Exception(() => PGPSignature.Verify(signature, newPublicKey)); Assert.NotNull(ex); Assert.IsType <PgpDataValidationException>(ex); }
public void VerifyString() { string text = "hello again world!"; string signature = GetSignatureString(text); Assert.NotNull(signature); Assert.NotEqual(string.Empty, signature); byte[] message = PGPSignature.Verify(signature, publicKey); Assert.NotNull(message); Assert.NotEqual(0, message.Length); Assert.Equal(text, Encoding.ASCII.GetString(message)); }
/// <summary> /// Verifies the Trust contained within the specified Manifest. /// </summary> /// <param name="manifest">The Manifest for which the Trust is to be verified.</param> /// <exception cref="InvalidDataException"> /// Thrown when the Manifest is Trusted but does not contain a Digest, when an error is encountered while verifying the /// Trust, or when the verified Trust does not match the Manifest's Digest. /// </exception> private void VerifyTrust(PackageManifest manifest) { string verifiedTrust = string.Empty; if (manifest.Signature.Trust != string.Empty) { Verbose("Verifying the Manifest Trust..."); if (string.IsNullOrEmpty(manifest.Signature.Digest)) { throw new InvalidDataException("the Manifest is Trusted but it contains no Digest to trust."); } byte[] trustBytes = Encoding.ASCII.GetBytes(manifest.Signature.Trust); byte[] verifiedTrustBytes; try { verifiedTrustBytes = PGPSignature.Verify(trustBytes, TrustPGPPublicKey); } catch (Exception ex) { throw new InvalidDataException($"an Exception was thrown while verifying the Trust: {ex.GetType().Name}: {ex.Message}"); } verifiedTrust = Encoding.ASCII.GetString(verifiedTrustBytes); if (manifest.Signature.Digest != verifiedTrust) { throw new InvalidDataException("the Manifest Trust is not valid; the Trusted Digest does not match the Digest in the Manifest."); } Verbose("Trust verified successfully."); } else { throw new InvalidDataException("the Manifest Trust is empty."); } }
/// <summary> /// Returns a PGP signature of the specified text using the default private key. /// </summary> /// <param name="text">The text for which the signature will be generated.</param> /// <returns>The generated PGP signature.</returns> private byte[] GetSignature(string text) { byte[] bytes = Encoding.ASCII.GetBytes(text); return(PGPSignature.Sign(bytes, privateKey, password)); }
public void SignZeroBytes() { byte[] signature = PGPSignature.Sign(new byte[0], privateKey, password); Assert.NotNull(Encoding.ASCII.GetString(signature)); }