<commit_before>// Copyright:: Copyright (c) 2015-2016 Chef Software, Inc.
//
// The terms of the Evaluation Agreement (Bldr) between Chef Software Inc. and the party accessing
// this file ("Licensee") apply to Licensee's use of the Software until such time that the Software
// is made available under an open source license such as the Apache 2.0 License.


use std::io::prelude::*;
use std::fs;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::env;
use std::mem;

use libsodium_sys;
use sodiumoxide::init as nacl_init;
use sodiumoxide::crypto::sign;
use sodiumoxide::crypto::sign::ed25519::SecretKey as SigSecretKey;
use sodiumoxide::crypto::sign::ed25519::PublicKey as SigPublicKey;
use sodiumoxide::crypto::box_::curve25519xsalsa20poly1305::PublicKey as BoxPublicKey;
use sodiumoxide::crypto::box_::curve25519xsalsa20poly1305::SecretKey as BoxSecretKey;
use rustc_serialize::base64::{STANDARD, ToBase64, FromBase64};
use time;

use error::{Error, Result};
use fs::KEY_CACHE;
use util::perm;

/// Habitat uses [libsodium](https://github.com/jedisct1/libsodium) and it's Rust counterpart [sodiumoxide](https://github./// com/dnaq/sodiumoxide) for cryptographic operations.
///
/// ### Concepts and terminology:
/// - All public keys/certificates/signatures will be referred to as **public**.
/// - All secret or private keys will be referred to as **secret**.
/// - The word `key` by itself does not indicate **public** or **secret**. The only exception is if the word key appears as /// part of a file suffix, where it is then considered the **secret key** file.
/// - **Origin** -  refers to build-time operations, including signing and verifification of an artifact.
/// - **Organization** - refers to run-time operations that can happen in Habitat, such as deploying a package signed in a /// different origin into your own organization.
/// - **Signing keys** - aka **sig** keys. These are used to sign and verify packages. Contains a `sig.key` file suffix. Sig /// keys are NOT compatible with box keys.
/// - **Box keys** - used for encryption/decryption of arbitrary data. Contains a `.box.key` file suffix. Box keys are NOT /// compatible with sig keys.
/// - **Key revisions** - Habitat can use several keys for any given user, service, or origin via different revision numbers. /// Revision numbers appear following the key name and are in the format
/// `{year}{month}{day}{hour24}{minute}{second}`. For all user-facing cryptographic operations (sign/verify/encrypt/decrypt), /// the latest key is tried first, and upon failure, Habitat will try keys in reverse chronological order until success or /// there are no more keys. ***TODO: key revisions are generated as part of a filename, but only the most recent key is used /// during crypto operations.***
///
///
/// Example origin key file names ("sig" keys):
///
/// ```
///  habitat-201603312016.pub
///  habitat-201603312016.sig.key
///  your_company-201604021516.pub
///  your_company-201604021516.sig.key
/// ```
///
///
/// Example user keys ("box" keys)
///
/// ```
///  dave@habitat-201603312016.pub
///  some_user@habitat-201603312016.pub
/// ```
///
/// Example Service keys:
///
/// ```
///  redis.default@habitat-box-201603312016.key
/// ```
///
/// ### Habitat signed artifact format
///
/// A signed `.hab` artifact has 3 plaintext lines followed by a binary blob of data, which is the unsigned tarfile.
///
/// - The first plaintext line is the name of the origin signing key that was used to sign this artifact.
/// - The second plaintext line is the hashing algorithm used, which will be `BLAKE2b` unless our use of crypto is expanded /// some time in the future.
/// - The third plaintext line is a base64 *signed* value of the binary blob's base64 file hash. Signing uses a secret origin /// key, while verifying uses the public origin key. Thus, it it safe to distribute public origin keys.
///
/// ```
/// BLAKE2b
/// signed BLAKE2b signature
/// binary-blob
/// ```
///
/// https://download.libsodium.org/doc/hashing/generic_hashing.html
///
/// It's possible to examine the contents of a `.hab` file from a Linux shell:
///
/// ```
/// $ head -3 /opt/bldr/cache/pkgs/chef-glibc-2.22-20160310192356.bldr
///
/// BLAKE2b
/// w4yC7/QADdC+NfH/wgN5u4K94nMieb1TxTVzbSfpMwRQ4k+YwhLs1nDXSIbSC8jHdF/7/LqLWtgPvGDmoKIvBDI0aGpIcGdlNDJhMDBnQ3lsMVVFM0JvRlZGSH/// hXcnBuWWF0SllXTXo1ZDg9
/// # Note that this is an example signature only
/// ```
///
/// It is also possible to extract a plain tarball from a signed `.hab` artifact using the following command:
///
/// ```
/// tail -n +4 /tmp/somefile.hab > somefile.tar
/// # start at line 4, skipping the first 3 plaintext lines.
/// ```

/// The suffix on the end of a public sig/box file
static PUB_KEY_SUFFIX: &'static str = "pub";

/// The suffix on the end of a public sig file
static SECRET_SIG_KEY_SUFFIX: &'static str = "sig.key";

/// The suffix on the end of a secret box file
static SECRET_BOX_KEY_SUFFIX: &'static str = "box.key";

/// The hashing function we're using during sign/verify<commit_msg>update embedded docs<commit_after>// Copyright:: Copyright (c) 2015-2016 Chef Software, Inc.
//
// The terms of the Evaluation Agreement (Bldr) between Chef Software Inc. and the party accessing
// this file ("Licensee") apply to Licensee's use of the Software until such time that the Software
// is made available under an open source license such as the Apache 2.0 License.


use std::io::prelude::*;
use std::fs;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::env;
use std::mem;

use libsodium_sys;
use sodiumoxide::init as nacl_init;
use sodiumoxide::crypto::sign;
use sodiumoxide::crypto::sign::ed25519::SecretKey as SigSecretKey;
use sodiumoxide::crypto::sign::ed25519::PublicKey as SigPublicKey;
use sodiumoxide::crypto::box_::curve25519xsalsa20poly1305::PublicKey as BoxPublicKey;
use sodiumoxide::crypto::box_::curve25519xsalsa20poly1305::SecretKey as BoxSecretKey;
use rustc_serialize::base64::{STANDARD, ToBase64, FromBase64};
use time;

use error::{Error, Result};
use fs::KEY_CACHE;
use util::perm;

/// Habitat uses [libsodium](https://github.com/jedisct1/libsodium) and it's Rust counterpart [sodiumoxide](https://github./// com/dnaq/sodiumoxide) for cryptographic operations.
///
/// ### Concepts and terminology:
/// - All public keys/certificates/signatures will be referred to as **public**.
/// - All secret or private keys will be referred to as **secret**.
/// - The word `key` by itself does not indicate **public** or **secret**. The only exception is if the word key appears as part of a /// file suffix, where it is then considered the **secret key** file.
/// - **Origin** -  refers to build-time operations, including signing and verifification of an artifact.
/// - **Organization** - refers to run-time operations that can happen in Habitat, such as deploying a package signed in a different /// origin into your own organization.
/// - **Signing keys** - aka **sig** keys. These are used to sign and verify packages. Contains a `sig.key` file suffix. Sig keys are /// NOT compatible with box keys.
/// - **Box keys** - used for encryption/decryption of arbitrary data. Contains a `.box.key` file suffix. Box keys are NOT compatible /// with sig keys.
/// - **Key revisions** - Habitat can use several keys for any given user, service, or origin via different revision numbers. Revision /// numbers appear following the key name and are in the format
/// `{year}{month}{day}{hour24}{minute}{second}`. For all user-facing cryptographic operations (sign/verify/encrypt/decrypt), the /// latest key is tried first, and upon failure, Habitat will try keys in reverse chronological order until success or there are no /// more keys. ***TODO: key revisions are generated as part of a filename, but only the most recent key is used during crypto operations/// .***
///
///
/// Example origin key file names ("sig" keys):
///
/// ```
///  habitat-201603312016.pub
///  habitat-201603312016.sig.key
///  your_company-201604021516.pub
///  your_company-201604021516.sig.key
/// ```
///
///
/// Example user keys ("box" keys)
///
/// ```
///  dave@habitat-201603312016.pub
///  some_user@habitat-201603312016.pub
/// ```
///
/// Example Service keys:
///
/// ```
///  redis.default@habitat-box-201603312016.key
/// ```
///
/// ### Habitat signed artifact format
///
/// A signed `.hab` artifact has 3 plaintext lines followed by a binary blob of data, which is the unsigned tarfile.
///
/// - The first plaintext line is the name of the origin signing key that was used to sign this artifact.
/// - The second plaintext line is the hashing algorithm used, which will be `BLAKE2b` unless our use of crypto is expanded some time /// in the future.
/// - The third plaintext line is a base64 *signed* value of the binary blob's base64 file hash. Signing uses a secret origin key, /// while verifying uses the public origin key. Thus, it it safe to distribute public origin keys.
///
/// Example header:
/// ```
/// habitat-20160405144945
/// BLAKE2b
/// signed BLAKE2b signature
/// <binary-blob>
/// ```
///
/// https://download.libsodium.org/doc/hashing/generic_hashing.html
///
/// It's possible to examine the contents of a `.hab` file from a Linux shell:
///
/// ```
/// $ head -3 /opt/bldr/cache/pkgs/chef-glibc-2.22-20160310192356.bldr
/// habitat-20160405144945
/// BLAKE2b
/// w4yC7/QADdC+NfH/wgN5u4K94nMieb1TxTVzbSfpMwRQ4k+YwhLs1nDXSIbSC8jHdF/7/LqLWtgPvGDmoKIvBDI0aGpIcGdlNDJhMDBnQ3lsMVVFM0JvRlZGSHhXcnBuWWF0/// SllXTXo1ZDg9
/// # Note that this is an example signature only
/// ```
///
/// It is also possible to extract a plain tarball from a signed `.hab` artifact using the following command:
///
/// ```
/// tail -n +4 /tmp/somefile.hab > somefile.tar
/// # start at line 4, skipping the first 3 plaintext lines.
/// ```


/// The suffix on the end of a public sig/box file
static PUB_KEY_SUFFIX: &'static str = "pub";

/// The suffix on the end of a public sig file
static SECRET_SIG_KEY_SUFFIX: &'static str = "sig.key";

/// The suffix on the end of a secret box file
static SECRET_BOX_KEY_SUFFIX: &'static str = "box.key";

/// The hashing function we're using during sign/verify
{'fraction_non_alphanumeric': 0.13793441979187118, 'fraction_numerical': 0.03848419399175339, 'mean_word_length': 3.5396613190730837, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 6, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7227834', 'n_tokens_mistral': 3414, 'n_tokens_neox': 3123, 'n_words': 1177}