Exemplo n.º 1
0
int fwfile_add_meta_conf_str(const char *configtxt, int configtxt_len,
                             struct archive *a, const unsigned char *signing_key)
{
    struct archive_entry *entry;

    // If the user passed in a signing key, sign the meta.conf.
    if (signing_key) {
        unsigned char signature[crypto_sign_BYTES];
        crypto_sign_detached(signature, NULL,
                             (unsigned char *) configtxt, configtxt_len,
                             signing_key);

        entry = archive_entry_new();
        archive_entry_set_pathname(entry, "meta.conf.ed25519");
        archive_entry_set_size(entry, sizeof(signature));
        archive_entry_set_filetype(entry, AE_IFREG);
        archive_entry_set_perm(entry, 0644);
        archive_write_header(a, entry);
        archive_write_data(a, signature, sizeof(signature));
        archive_entry_free(entry);
    }

    // Add meta.conf
    entry = archive_entry_new();
    archive_entry_set_pathname(entry, "meta.conf");
    archive_entry_set_size(entry, configtxt_len);
    archive_entry_set_filetype(entry, AE_IFREG);
    archive_entry_set_perm(entry, 0644);
    archive_write_header(a, entry);
    archive_write_data(a, configtxt, configtxt_len);
    archive_entry_free(entry);

    return 0;
}
Exemplo n.º 2
0
int
crypto_sign(unsigned char *sm, unsigned long long *smlen_p,
            const unsigned char *m, unsigned long long mlen,
            const unsigned char *sk)
{
    unsigned long long siglen;

    memmove(sm + crypto_sign_ed25519_BYTES, m, mlen);
/* LCOV_EXCL_START */
    if (crypto_sign_detached(sm, &siglen, sm + crypto_sign_ed25519_BYTES,
                             mlen, sk) != 0 ||
        siglen != crypto_sign_ed25519_BYTES) {
        if (smlen_p != NULL) {
            *smlen_p = 0;
        }
        memset(sm, 0, mlen + crypto_sign_ed25519_BYTES);
        return -1;
    }
/* LCOV_EXCL_STOP */

    if (smlen_p != NULL) {
        *smlen_p = mlen + siglen;
    }
    return 0;
}
Exemplo n.º 3
0
SEXP R_sig_sign(SEXP msg, SEXP key) {
    if(LENGTH(key) != crypto_sign_SECRETKEYBYTES)
        Rf_error("Invalid key: must be exactly %d bytes", crypto_sign_SECRETKEYBYTES);
    SEXP res = allocVector(RAWSXP, crypto_sign_BYTES);
    if(crypto_sign_detached(RAW(res), NULL, RAW(msg), LENGTH(msg), RAW(key)))
        Rf_error("Failed to create signature");
    return res;
}
Exemplo n.º 4
0
void RippleAddress::sign(uint256 const& message, Blob& retSignature) const
{
	assert(vchData.size() == 64);

	const unsigned char *key = vchData.data();
	retSignature.resize(crypto_sign_BYTES);
	crypto_sign_detached(&retSignature[0], NULL,
		(unsigned char*)message.begin(), message.size(),
		key);
}
Exemplo n.º 5
0
CWalletTx GetValidReceive(ZCJoinSplit& params,
                          const libzcash::SpendingKey& sk, CAmount value,
                          bool randomInputs) {
    CMutableTransaction mtx;
    mtx.nVersion = 2; // Enable JoinSplits
    mtx.vin.resize(2);
    if (randomInputs) {
        mtx.vin[0].prevout.hash = GetRandHash();
        mtx.vin[1].prevout.hash = GetRandHash();
    } else {
        mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
        mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
    }
    mtx.vin[0].prevout.n = 0;
    mtx.vin[1].prevout.n = 0;

    // Generate an ephemeral keypair.
    uint256 joinSplitPubKey;
    unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
    crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey);
    mtx.joinSplitPubKey = joinSplitPubKey;

    boost::array<libzcash::JSInput, 2> inputs = {
        libzcash::JSInput(), // dummy input
        libzcash::JSInput() // dummy input
    };

    boost::array<libzcash::JSOutput, 2> outputs = {
        libzcash::JSOutput(sk.address(), value),
        libzcash::JSOutput(sk.address(), value)
    };

    boost::array<libzcash::Note, 2> output_notes;

    // Prepare JoinSplits
    uint256 rt;
    JSDescription jsdesc {params, mtx.joinSplitPubKey, rt,
                          inputs, outputs, 2*value, 0, false};
    mtx.vjoinsplit.push_back(jsdesc);

    // Empty output script.
    CScript scriptCode;
    CTransaction signTx(mtx);
    uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL);

    // Add the signature
    assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
                                dataToBeSigned.begin(), 32,
                                joinSplitPrivKey
                               ) == 0);

    CTransaction tx {mtx};
    CWalletTx wtx {NULL, tx};
    return wtx;
}
Exemplo n.º 6
0
int cpn_sign_sig(struct cpn_sign_sig *out, const struct cpn_sign_sk *key,
        uint8_t *data, size_t datalen)
{
    memset(out, 0, sizeof(*out));

    if (crypto_sign_detached(out->data, NULL, data, datalen, key->data) != 0) {
        cpn_log(LOG_LEVEL_ERROR, "Could not sign data");
        return -1;
    }

    return 0;
}
Exemplo n.º 7
0
// Computes the signature of a message.
int EdDSA::sign(unsigned char* msg, unsigned long long msglen, unsigned char* sig) {
    unsigned char pubKey[crypto_sign_PUBLICKEYBYTES];
    unsigned char privKey[crypto_sign_SECRETKEYBYTES];
    int check;

    check = crypto_sign_seed_keypair(pubKey, privKey,
                                     (const unsigned char*)this->keySeed);
    if (check != 0) {
        // Something went wrong deriving keys.
        return(0);
    }
    check = crypto_sign_detached(sig, NULL, msg, msglen, privKey);
    if (check != 0) {
        // Something went wrong signing the message.
        return(0);
    }
    return(crypto_sign_BYTES + msglen);
}
Exemplo n.º 8
0
int
crypto_sign(unsigned char *sm, unsigned long long *smlen,
            const unsigned char *m, unsigned long long mlen,
            const unsigned char *sk)
{
    unsigned long long siglen;

    if (crypto_sign_detached(sm, &siglen, m, mlen, sk) != 0 ||
        siglen > crypto_sign_ed25519_BYTES) {
        if (smlen != NULL) {
            *smlen = 0;
        }
        memset(sm, 0, mlen + crypto_sign_ed25519_BYTES);
        return -1;
    }
    memmove(sm + siglen, m, mlen);
    if (smlen != NULL) {
        *smlen = mlen + siglen;
    }
    return 0;
}
Exemplo n.º 9
0
CWalletTx GetValidSpend(ZCJoinSplit& params,
                        const libzcash::SpendingKey& sk,
                        const libzcash::Note& note, CAmount value) {
    CMutableTransaction mtx;
    mtx.vout.resize(2);
    mtx.vout[0].nValue = value;
    mtx.vout[1].nValue = 0;

    // Generate an ephemeral keypair.
    uint256 joinSplitPubKey;
    unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
    crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey);
    mtx.joinSplitPubKey = joinSplitPubKey;

    // Fake tree for the unused witness
    ZCIncrementalMerkleTree tree;

    libzcash::JSOutput dummyout;
    libzcash::JSInput dummyin;

    {
        if (note.value > value) {
            libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
            libzcash::PaymentAddress dummyaddr = dummykey.address();
            dummyout = libzcash::JSOutput(dummyaddr, note.value - value);
        } else if (note.value < value) {
            libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
            libzcash::PaymentAddress dummyaddr = dummykey.address();
            libzcash::Note dummynote(dummyaddr.a_pk, (value - note.value), uint256(), uint256());
            tree.append(dummynote.cm());
            dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey);
        }
    }

    tree.append(note.cm());

    boost::array<libzcash::JSInput, 2> inputs = {
        libzcash::JSInput(tree.witness(), note, sk),
        dummyin
    };

    boost::array<libzcash::JSOutput, 2> outputs = {
        dummyout, // dummy output
        libzcash::JSOutput() // dummy output
    };

    boost::array<libzcash::Note, 2> output_notes;

    // Prepare JoinSplits
    uint256 rt = tree.root();
    JSDescription jsdesc {params, mtx.joinSplitPubKey, rt,
                          inputs, outputs, 0, value, false};
    mtx.vjoinsplit.push_back(jsdesc);

    // Empty output script.
    CScript scriptCode;
    CTransaction signTx(mtx);
    uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL);

    // Add the signature
    assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
                                dataToBeSigned.begin(), 32,
                                joinSplitPrivKey
                               ) == 0);
    CTransaction tx {mtx};
    CWalletTx wtx {NULL, tx};
    return wtx;
}
Exemplo n.º 10
0
static int
sign(const char *sk_file, const char *message_file, const char *sig_file,
     const char *comment, const char *trusted_comment, int hashed)
{
    unsigned char  global_sig[crypto_sign_BYTES];
    SigStruct      sig_struct;
    FILE          *fp;
    SeckeyStruct  *seckey_struct;
    unsigned char *message;
    unsigned char *sig_and_trusted_comment;
    size_t         comment_len;
    size_t         trusted_comment_len;
    size_t         message_len;

    seckey_struct = seckey_load(sk_file);
    message = message_load(&message_len, message_file, hashed);
    if (hashed != 0) {
        memcpy(sig_struct.sig_alg, SIGALG_HASHED, sizeof sig_struct.sig_alg);
    } else {
        memcpy(sig_struct.sig_alg, SIGALG, sizeof sig_struct.sig_alg);
    }
    memcpy(sig_struct.keynum, seckey_struct->keynum_sk.keynum,
           sizeof sig_struct.keynum);
    crypto_sign_detached(sig_struct.sig, NULL, message, message_len,
                         seckey_struct->keynum_sk.sk);
    free(message);
    if ((fp = fopen(sig_file, "w")) == NULL) {
        exit_err(sig_file);
    }
    comment_len = strlen(comment);
    assert(strrchr(comment, '\r') == NULL && strrchr(comment, '\n') == NULL);
    assert(COMMENTMAXBYTES > sizeof COMMENT_PREFIX);
    if (comment_len >= COMMENTMAXBYTES - sizeof COMMENT_PREFIX) {
        fprintf(stderr, "Warning: comment too long. "
                "This breaks compatibility with signify.\n");
    }
    xfprintf(fp, "%s%s\n", COMMENT_PREFIX, comment);
    xfput_b64(fp, (unsigned char *) (void *) &sig_struct, sizeof sig_struct);

    xfprintf(fp, "%s%s\n", TRUSTED_COMMENT_PREFIX, trusted_comment);
    trusted_comment_len = strlen(trusted_comment);
    assert(strrchr(trusted_comment, '\r') == NULL &&
           strrchr(trusted_comment, '\n') == NULL);
    if (trusted_comment_len >=
        TRUSTEDCOMMENTMAXBYTES - sizeof TRUSTED_COMMENT_PREFIX) {
        exit_msg("Trusted comment too long");
    }
    sig_and_trusted_comment = xmalloc((sizeof sig_struct.sig) +
                                      trusted_comment_len);
    memcpy(sig_and_trusted_comment, sig_struct.sig, sizeof sig_struct.sig);
    memcpy(sig_and_trusted_comment + sizeof sig_struct.sig, trusted_comment,
           trusted_comment_len);
    crypto_sign_detached(global_sig, NULL, sig_and_trusted_comment,
                         (sizeof sig_struct.sig) + trusted_comment_len,
                         seckey_struct->keynum_sk.sk);
    sodium_free(seckey_struct);
    xfput_b64(fp, (unsigned char *) (void *) &global_sig, sizeof global_sig);
    free(sig_and_trusted_comment);
    xfclose(fp);

    return 0;
}
Exemplo n.º 11
0
void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t consensusBranchId) {
    tx.fOverwintered = insecure_rand() % 2;
    if (tx.fOverwintered) {
        if (insecure_rand() % 2) {
            tx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
            tx.nVersion = sapling_version_dist(rng);
        } else {
            tx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
            tx.nVersion = overwinter_version_dist(rng);
        }
        tx.nExpiryHeight = (insecure_rand() % 2) ? insecure_rand() : 0;
    } else {
        tx.nVersion = insecure_rand() & 0x7FFFFFFF;
    }
    tx.vin.clear();
    tx.vout.clear();
    tx.vShieldedSpend.clear();
    tx.vShieldedOutput.clear();
    tx.vjoinsplit.clear();
    tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0;
    int ins = (insecure_rand() % 4) + 1;
    int outs = fSingle ? ins : (insecure_rand() % 4) + 1;
    int shielded_spends = (insecure_rand() % 4) + 1;
    int shielded_outs = (insecure_rand() % 4) + 1;
    int joinsplits = (insecure_rand() % 4);
    for (int in = 0; in < ins; in++) {
        tx.vin.push_back(CTxIn());
        CTxIn &txin = tx.vin.back();
        txin.prevout.hash = GetRandHash();
        txin.prevout.n = insecure_rand() % 4;
        RandomScript(txin.scriptSig);
        txin.nSequence = (insecure_rand() % 2) ? insecure_rand() : (unsigned int)-1;
    }
    for (int out = 0; out < outs; out++) {
        tx.vout.push_back(CTxOut());
        CTxOut &txout = tx.vout.back();
        txout.nValue = insecure_rand() % 100000000;
        RandomScript(txout.scriptPubKey);
    }
    if (tx.nVersionGroupId == SAPLING_VERSION_GROUP_ID) {
        tx.valueBalance = insecure_rand() % 100000000;
        for (int spend = 0; spend < shielded_spends; spend++) {
            SpendDescription sdesc;
            sdesc.cv = GetRandHash();
            sdesc.anchor = GetRandHash();
            sdesc.nullifier = GetRandHash();
            sdesc.rk = GetRandHash();
            randombytes_buf(sdesc.zkproof.begin(), sdesc.zkproof.size());
            tx.vShieldedSpend.push_back(sdesc);
        }
        for (int out = 0; out < shielded_outs; out++) {
            OutputDescription odesc;
            odesc.cv = GetRandHash();
            odesc.cm = GetRandHash();
            odesc.ephemeralKey = GetRandHash();
            randombytes_buf(odesc.encCiphertext.begin(), odesc.encCiphertext.size());
            randombytes_buf(odesc.outCiphertext.begin(), odesc.outCiphertext.size());
            randombytes_buf(odesc.zkproof.begin(), odesc.zkproof.size());
            tx.vShieldedOutput.push_back(odesc);
        }
    }
    if (tx.nVersion >= 2) {
        for (int js = 0; js < joinsplits; js++) {
            JSDescription jsdesc;
            if (insecure_rand() % 2 == 0) {
                jsdesc.vpub_old = insecure_rand() % 100000000;
            } else {
                jsdesc.vpub_new = insecure_rand() % 100000000;
            }

            jsdesc.anchor = GetRandHash();
            jsdesc.nullifiers[0] = GetRandHash();
            jsdesc.nullifiers[1] = GetRandHash();
            jsdesc.ephemeralKey = GetRandHash();
            jsdesc.randomSeed = GetRandHash();
            randombytes_buf(jsdesc.ciphertexts[0].begin(), jsdesc.ciphertexts[0].size());
            randombytes_buf(jsdesc.ciphertexts[1].begin(), jsdesc.ciphertexts[1].size());
            if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
                libzcash::GrothProof zkproof;
                randombytes_buf(zkproof.begin(), zkproof.size());
                jsdesc.proof = zkproof;
            } else {
                jsdesc.proof = libzcash::PHGRProof::random_invalid();
            }
            jsdesc.macs[0] = GetRandHash();
            jsdesc.macs[1] = GetRandHash();

            tx.vjoinsplit.push_back(jsdesc);
        }

        unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
        crypto_sign_keypair(tx.joinSplitPubKey.begin(), joinSplitPrivKey);

        // Empty output script.
        CScript scriptCode;
        CTransaction signTx(tx);
        uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);

        assert(crypto_sign_detached(&tx.joinSplitSig[0], NULL,
                                    dataToBeSigned.begin(), 32,
                                    joinSplitPrivKey
                                    ) == 0);
    }
}
Exemplo n.º 12
0
int32_t mail_responder(uint32_t socket)
{
  #ifdef DEBUG
  printf("Entering MAIL subroutine\n");
  #endif /*DEBUG*/
  //Allocate general variables

  //Allocate primary buffers and counters
  char source_account_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t source_account_length = 0;
  char source_domain_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t source_domain_length = 0;
  char dest_account_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t dest_account_length = 0;
  char dest_domain_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t dest_domain_length = 0;
  uint32_t version = 0;
  uint32_t attachment_count = 0;
  uint64_t message_length = 0;
  uint64_t log_length = 0;
  //Generate unique file from current time and current FD
  //Get time with nanosecond resolution (or so they say)
  struct timespec time_for_file;
  clock_gettime(CLOCK_REALTIME, &time_for_file);
  //Mix time with FD and hash
  //We are hashing two ints and a long, so
  char meat_and_potatoes[24] = {0};
  //memset(meat_and_potatoes, 0, sizeof(meat_and_potatoes));
  memcpy(meat_and_potatoes, &time_for_file.tv_sec, sizeof(time_for_file.tv_sec));
  memcpy(meat_and_potatoes+sizeof(time_for_file.tv_sec), &socket, sizeof(socket));
  memcpy(meat_and_potatoes+sizeof(time_for_file.tv_sec)+sizeof(socket), &time_for_file.tv_nsec, sizeof(time_for_file.tv_nsec));
  unsigned char hash[64]; //64 bytes because hash has a fixed size output
  crypto_generichash(hash, sizeof(hash), (const unsigned char *)meat_and_potatoes, sizeof(meat_and_potatoes),NULL, 0);

  //Get file ready to write
  //TODO needs to be /mail/user/unique_file_name
  char unique_file_name[129] = {0};

  //char base64_username[341] = {0};
  char unique_file_location[522] = {0};
  //TODO Need to check if user is part of this domain. If not the file location should be some temporary storage.

  //unique_file_name_length is not currently used. Should be fine.
  uint32_t unique_file_name_length = base64_encode((char *)hash, sizeof(hash), unique_file_name, sizeof(unique_file_name), (char *)filesystem_safe_base64_string, 64);
  if (unique_file_name_length<=0)
  {
    perror("base64_encode. unique_file_name failed to be created");
    print_to_log("base64_encode failed to create a unique_file_name.", LOG_ERR);
    return -1;
  }
  //uint32_t base64_username_length = base64_encode((char *)dest_account_buffer, strlen(dest_account_buffer), base64_username, strlen(base64_username), (char *)filesystem_safe_base64_string, 64);
  //Read primary routing and processing information
  //First read in fixed length fields
  if (read_n_bytes(socket, (unsigned char *)&version, 4)!=4)
  {
    perror("read_n_bytes version");
    print_to_log("Read error while reading crypto type", LOG_ERR);
    return -1;
  }
  if (read_n_bytes(socket, (unsigned char *)&attachment_count, 4)!=4)
  {
    perror("read_n_bytes attachment_count");
    print_to_log("Read error while reading attachment count", LOG_ERR);
    return -1;
  }
  if (read_n_bytes(socket, (unsigned char *)&log_length, 8)!=8)
  {
    perror("read_n_bytes log_length");
    print_to_log("Read error while reading message length", LOG_ERR);
    return -1;
  }
  if (read_n_bytes(socket, (unsigned char *)&message_length, 8)!=8)
  {
    perror("read_n_bytes message_length");
    print_to_log("Read error while reading message length", LOG_ERR);
    return -1;
  }
  //Read in account and domain info
  if ((dest_account_length=read_until(socket, (unsigned char *)dest_account_buffer, sizeof(dest_account_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading dest_account_buffer", LOG_ERR);
    return -1;
  }
  if (snprintf(unique_file_location, sizeof(unique_file_location), "%s%s%s%s", "/mail/", dest_account_buffer, "/" , unique_file_name)<0)
  {
    perror("snprintf");
    print_to_log("snprintf failed to create a new file string. Cannot write message out",LOG_ERR);
    return -1;
  }
  write_to_file((char *)&version, 4, unique_file_location);
  version = be32toh(version);
  write_to_file((char *)&attachment_count, 4, unique_file_location);
  attachment_count = be32toh(attachment_count);
  write_to_file((char *)&log_length, 8, unique_file_location);
  log_length = be64toh(log_length);
  write_to_file((char *)&message_length, 8, unique_file_location);
  message_length = be64toh(message_length);
  #ifdef DEBUG
  printf("Writing mail to %s\n", unique_file_location);
  printf("Log length = %ld\n", log_length);
  printf("Version = %d\n", version);
  printf("Attachment count = %d\n", attachment_count);
  printf("Message length = %ld\n", message_length);
  #endif /*DEBUG*/

  write_to_file(dest_account_buffer, dest_account_length, unique_file_location);
  #ifdef DEBUG
  printf("dest_account_length = %d\n", dest_account_length);
  #endif /*DEBUG*/
  if ((dest_domain_length=read_until(socket, (unsigned char *)dest_domain_buffer, sizeof(dest_domain_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading dest_domain_buffer", LOG_ERR);
    return -1;
  }
  write_to_file(dest_domain_buffer, dest_domain_length, unique_file_location);
  #ifdef DEBUG
  printf("dest_domain_length = %d\n", dest_domain_length);
  #endif /*DEBUG*/
  //Check if this is the destination
  if((strcmp(dest_domain_buffer, home_domain)!=0)&&(forward==0))
  {
    //Send delivery failure, close connection, clean up and return.
    unsigned char signature_of_DELIVERYFAILURE[crypto_sign_BYTES] = {0};
    unsigned char write_buffer[sizeof(network_crypto_version)+sizeof(server_public_key)+sizeof(signature_of_DELIVERYFAILURE)+2];
    crypto_sign_detached(signature_of_DELIVERYFAILURE, NULL, signature_of_DELIVERYFAILURE, sizeof(signature_of_DELIVERYFAILURE), server_private_key);
    memcpy(write_buffer, &network_crypto_version, sizeof(network_crypto_version));
    memcpy(write_buffer+sizeof(network_crypto_version), cmtp_reply_DELIVERYFAILURE, sizeof(cmtp_reply_DELIVERYFAILURE));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_DELIVERYFAILURE), &signature_of_DELIVERYFAILURE, sizeof(signature_of_DELIVERYFAILURE));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_DELIVERYFAILURE)+sizeof(signature_of_DELIVERYFAILURE), &termination_char, sizeof(termination_char));
    write(socket, write_buffer, sizeof(write_buffer));
  }

  if ((source_account_length=read_until(socket, (unsigned char *)source_account_buffer, sizeof(source_account_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading source_account_buffer", LOG_ERR);
    return -1;
  }
  write_to_file(source_account_buffer, source_account_length, unique_file_location);
  #ifdef DEBUG
  printf("source_account_length = %d\n", source_account_length);
  #endif /*DEBUG*/
  if ((source_domain_length=read_until(socket, (unsigned char *)source_domain_buffer, sizeof(source_domain_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading source_domain_buffer", LOG_ERR);
    return -1;
  }
  write_to_file(source_domain_buffer, source_domain_length, unique_file_location);
  #ifdef DEBUG
  printf("source_domain_length = %d\n", source_domain_length);
  #endif /*DEBUG*/
  //This completes the read of the header


  //uint64_t numeric_message_length = be64toh(*(uint64_t*)(&(message_length[0])));
  //uint64_t numeric_log_length = be64toh(*(uint64_t*)(&(log_length[0])));

  char temp_byte[1] = {0};
  //Read log
  for (uint64_t i = 0; i<log_length; i++)
  {
    if (read(socket, temp_byte, 1)<1)
    {
      print_to_log("read error while reading message body", LOG_ERR);
      perror("read");
      return -1;
    }
    write_to_file(temp_byte, 1, unique_file_location);
  }
  //Read message body
  for (uint64_t i = 0; i<message_length; i++)
  {
    if (read(socket, temp_byte, 1)<1)
    {
      print_to_log("read error while reading message body", LOG_ERR);
      perror("read");
      return -1;
    }
    write_to_file(temp_byte, 1, unique_file_location);
  }

  #ifdef DEBUG
  printf("Message body finished. Moving to attachment handling.\n");
  #endif /*DEBUG*/
  //Read for attachment
  //uint32_t numeric_attachment_count = be32toh(*(uint32_t*)(&(attachment_count[0])));
  temp_byte[0] = 0;
  for (uint64_t i = 0; i<attachment_count; i++)
  {
    if (read(socket, temp_byte, 1)<1)
    {
      print_to_log("read error while reading message body", LOG_ERR);
      perror("read");
      return -1;
    }
    write_to_file(temp_byte, 1, unique_file_location);
  }
  #ifdef DEBUG
  printf("Mail destin for %s\n", dest_domain_buffer);
  printf("Server domain is %s\n", home_domain);
  #endif /*DEBUG*/

  //Destination cases
   if ((memcmp(dest_domain_buffer, home_domain, dest_domain_length)==0)&&(memcmp(dest_account_buffer,"",1))==0)
   {
     #ifdef DEBUG
     printf("Devlivered mail is for server. Begin processing.\n");
     #endif /*DEBUG*/
     print_to_log("Mail has arrived for the server. Processing.",LOG_INFO);
     //Destination is this domain and for the server
   }
   else if ((memcmp(dest_domain_buffer, home_domain, dest_domain_length)==0))
   {
     #ifdef DEBUG
     printf("Devlivered mail is for a user on this domain. Store.\n");
     #endif /*DEBUG*/
     print_to_log("Mail has arrived for a user on this domain. Storing.",LOG_INFO);
     //Destination is for a user at this domain
   }
   else
   {
     #ifdef DEBUG
     printf("Devlivered mail is not destined for this domain. Forward to %s\n", dest_domain_buffer);
     #endif /*DEBUG*/
     print_to_log("Mail has arrived for another domain. Forwarding.",LOG_INFO);
     forwardMessage(unique_file_location, dest_domain_buffer);
     //Destination is on the web. Forward message.
   }
   #ifdef DEBUG
   printf("Mail section complete. Returning to mail loop.\n");
   #endif /*DEBUG*/
   return 0;
}
Exemplo n.º 13
0
int32_t login_responder(uint32_t socket)
{
  #ifdef DEBUG
	printf("Begin login_responder\n");
	#endif /**/
  char login_username_buffer[ROUTING_FIELD_SIZE] = {0};
  //char login_command_buffer[THREAD_COMMAND_BUFFER_SIZE] = {0};
  char xzibit_path_buffer[359] = {0};
  //uint32_t i = 0;
  read_until(socket, (unsigned char *)login_username_buffer, sizeof(login_username_buffer), termination_char);
  // #ifdef DEBUG
  // printf("login_username_buffer looks like:\n");
  // for (int j = 0; j<i;j++)
  // {
  //   printf("%x  :  %c\n", login_username_buffer[j]);
  // }
  // #endif /*DEBUG*/
  if (snprintf(xzibit_path_buffer, sizeof(xzibit_path_buffer), "%s%s%s%s%s", "/mail/", login_username_buffer, "/", login_username_buffer , ".xzibit")<0)
  {
    perror("snprintf");
    print_to_log("snprintf error. Cannot check for user public key", LOG_ERR);
  }
  #ifdef DEBUG
  printf("Checking for user xzibit at %s\n", xzibit_path_buffer);
  #endif /*DEBUG*/
  if (access(xzibit_path_buffer,R_OK)<0)
  {
    perror("access to user xzibit");
    print_to_log("Cannot access user xzibit. User not valid", LOG_ERR);
    return -1;
  }
  else
  {
    //Read Xzibit to buffer
    int xzibit_fd = open(xzibit_path_buffer, O_RDONLY);
    struct stat xzibit_stats;
    fstat(xzibit_fd, &xzibit_stats);
    uint64_t xzibit_size = xzibit_stats.st_size;
    unsigned char * xzibit = calloc(1, xzibit_size);
    if(read(xzibit_fd, xzibit, xzibit_size)<0)
    {
      perror("Reading user xzibit has gone wrong!");
      print_to_log("Reading user xzibit has gone wrong. Abort!", LOG_ERR);
      free(xzibit);
      return -1;
    }
    #ifdef DEBUG
    printf("Xzibit size = %ld\n", xzibit_size);
    #endif /*DEBUG*/
    //Sign xzibit
    unsigned char * server_sign_of_xzibit = calloc(1, 64);
    if (crypto_sign_detached(server_sign_of_xzibit, NULL, xzibit, xzibit_size, server_private_key)!=0)
    {
      perror("crypto_sign_detached failed in login responder");
      print_to_log("crypto_sign_detached failed in login responder", LOG_ERR);
      free(xzibit);
      free(server_sign_of_xzibit);
      return -1;
    }
    //Write it to the wire
    #ifdef DEBUG
    printf("Writing xzibit to the wire\n");
    #endif /*DEBUG*/
    if (write(socket, xzibit, xzibit_size)<0)
    {
      perror("Writing xzibit to the wire has failed");
      print_to_log("Writing xzibit to the wire has failed", LOG_ERR);
      free(xzibit);
      free(server_sign_of_xzibit);
      return -1;
    }
    free(xzibit);
    #ifdef DEBUG
    printf("After writing xzibit\n");
    #endif /*DEBUG*/
    if (write(socket, server_sign_of_xzibit, 64)<0)
    {
      perror("Writing server_sign_of_xzibit to the wire has failed");
      print_to_log("Writing server_sign_of_xzibit to the wire has failed", LOG_ERR);
      free(server_sign_of_xzibit);
      return -1;
    }
    free(server_sign_of_xzibit);
    #ifdef DEBUG
    printf("After writing signature\n");
    #endif /*DEBUG*/
  }
  return 0;
}
Exemplo n.º 14
0
int32_t keyrequest_responder(uint32_t socket)
{
  //Read until null
  uint32_t i = 0;
  char base64_username[341] = {0};
  char pub_key_path[358] = {0};
  char user_keyrequest_buffer[ROUTING_FIELD_SIZE] = {0};
  char domain_keyrequest_buffer[ROUTING_FIELD_SIZE] = {0};
  unsigned char user_public_key[crypto_sign_ed25519_PUBLICKEYBYTES] = {0};
  unsigned char signature_of_public_key[crypto_sign_BYTES] = {0};
  unsigned char signature_of_KEYNOTAVAILABLE[crypto_sign_BYTES] = {0};
  unsigned char write_buffer[sizeof(network_crypto_version)+sizeof(server_public_key)+sizeof(signature_of_public_key)+2];
  //Read in username
  do {
    read(socket, user_keyrequest_buffer+i, 1);
    if (user_keyrequest_buffer[i]==-1)
    {
      #ifdef DEBUG
      printf("Negative return value in main read loop. Killing everything!\n");
      return 0;
      #endif /*DEBUG*/
    }
    i++;
  } while((i<sizeof(user_keyrequest_buffer))&&(user_keyrequest_buffer[i-1]!='\0'));
  if (memcmp(user_keyrequest_buffer, &termination_char, 1)==0)
  {
    crypto_sign_detached(signature_of_public_key, NULL, server_public_key, sizeof(server_public_key), server_private_key);
    //Wants server key. Reply and return.
    //Create single buffer
    memcpy(write_buffer, &network_crypto_version, sizeof(network_crypto_version));
    memcpy(write_buffer+sizeof(network_crypto_version), server_public_key, sizeof(server_public_key));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(server_public_key), &termination_char, sizeof(termination_char));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(server_public_key)+sizeof(termination_char), signature_of_public_key, sizeof(signature_of_public_key));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(server_public_key)+sizeof(termination_char)+sizeof(signature_of_public_key), &termination_char, sizeof(termination_char));
    write(socket, write_buffer, sizeof(write_buffer));
    // write(socket, server_public_key, sizeof(server_public_key));
    // write(socket, &termination_char, sizeof(termination_char));
    // write(socket, signature_of_public_key, sizeof(signature_of_public_key));
    // write(socket, &termination_char, sizeof(termination_char));
    return 0;
    //Need to end here. Might need to functionize this code.
  }
  else
  {
    //uint32_t base64_username_length = base64_encode((char *)user_keyrequest_buffer, strlen(user_keyrequest_buffer), base64_username, strlen(base64_username), (char *)filesystem_safe_base64_string, 64);
    #ifdef DEBUG
    printf("Requested user = %s\n", user_keyrequest_buffer);
    #endif /*DEBUG*/
    do {
      read(socket, domain_keyrequest_buffer+i, 1);
      i++;
    } while((i<sizeof(domain_keyrequest_buffer))&&(domain_keyrequest_buffer[i-1]!='\0'));

    if (memcmp(&domain_keyrequest_buffer, &home_domain, ROUTING_FIELD_SIZE)!=0)
    {
      //Keyrequest is for a different domain. Query that domain and relay key.
    }

    if (snprintf(pub_key_path, sizeof(pub_key_path), "%s%s%s", "/mail/", user_keyrequest_buffer, "/public.key")<0)
    {
      perror("snprintf");
      print_to_log("snprintf error. Cannot check for user public key", LOG_ERR);
    }
    //Check for user's key in /mail/base64_username/public.key
    if (access(pub_key_path, R_OK)<0)
    {
      //User does not exist. Send error.
      perror("user access");
      #ifdef DEBUG
      printf("Key not found at %s\n", pub_key_path);
      #endif /*DEBUG*/
      print_to_log("Cannot access user public key. User does not exist.", LOG_ERR);
      //cmtp_reply_KEYNOTAVAILABLE includes the trailing null!
      crypto_sign_detached(signature_of_KEYNOTAVAILABLE, NULL, (const unsigned char *)cmtp_reply_KEYNOTAVAILABLE, sizeof(cmtp_reply_KEYNOTAVAILABLE), server_private_key);

      memcpy(write_buffer, &network_crypto_version, sizeof(network_crypto_version));
      memcpy(write_buffer+sizeof(cmtp_reply_KEYNOTAVAILABLE), cmtp_reply_KEYNOTAVAILABLE, sizeof(cmtp_reply_KEYNOTAVAILABLE));
      memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_KEYNOTAVAILABLE), &signature_of_KEYNOTAVAILABLE, sizeof(signature_of_KEYNOTAVAILABLE));
      memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_KEYNOTAVAILABLE)+sizeof(signature_of_KEYNOTAVAILABLE), signature_of_public_key, sizeof(signature_of_public_key));
      memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_KEYNOTAVAILABLE)+sizeof(signature_of_KEYNOTAVAILABLE)+sizeof(signature_of_public_key), &termination_char, sizeof(termination_char));
      #ifdef DEBUG
      //print_buffer (cmtp_reply_KEYNOTAVAILABLE, 32, "Key not available message: ", 32, 1);
      //print_buffer (signature_of_public_key, 64, "Key not available signature: ", 64, 1);
      #endif /*DEBUG*/
      write(socket, write_buffer, sizeof(write_buffer));

      // write(socket, &network_crypto_version, sizeof(network_crypto_version));
      // write(socket, cmtp_reply_KEYNOTAVAILABLE, sizeof(cmtp_reply_KEYNOTAVAILABLE));
      // write(socket, signature_of_KEYNOTAVAILABLE, sizeof(signature_of_KEYNOTAVAILABLE));
      // write(socket, &termination_char, sizeof(termination_char));

    }
    else         //Read public key and reply to request with it.
    {
      int32_t user_key_descriptor = open(pub_key_path, O_RDONLY);
      if (user_key_descriptor<0)
      {
        perror("open");
        print_to_log("Cannot open user public key", LOG_ERR);
      }
      if (read(user_key_descriptor, user_public_key, sizeof(user_public_key))<0)
      {
        perror("read");
        print_to_log("Error reading user public key", LOG_ERR);
      }
      //Sign key and store signature in signature_of_public_key
      crypto_sign_detached(signature_of_public_key, NULL, user_public_key, sizeof(user_public_key), server_private_key);
      //Send it all
      memcpy(write_buffer, &network_crypto_version, sizeof(network_crypto_version));
      memcpy(write_buffer+sizeof(network_crypto_version), user_public_key, sizeof(user_public_key));
      memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(user_public_key), &termination_char, sizeof(termination_char));
      memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(user_public_key)+sizeof(termination_char), signature_of_public_key, sizeof(signature_of_public_key));
      memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(user_public_key)+sizeof(termination_char)+sizeof(signature_of_public_key), &termination_char, sizeof(termination_char));
      #ifdef DEBUG
      //print_buffer (user_public_key, 32, "User public key: ", 32, 1);
      //print_buffer (signature_of_public_key, 64, "User public key signature: ", 64, 1);
      #endif /*DEBUG*/
      write(socket, write_buffer, sizeof(write_buffer));

      // write(socket, &network_crypto_version, sizeof(network_crypto_version));
      // write(socket, user_public_key, sizeof(user_public_key));
      // write(socket, &termination_char, sizeof(termination_char));
      // write(socket, signature_of_public_key, sizeof(signature_of_public_key));
      // write(socket, &termination_char, sizeof(termination_char));
      printf("Sent %ld bytes\n", sizeof(network_crypto_version)+sizeof(user_public_key)+sizeof(termination_char)+sizeof(signature_of_public_key)+sizeof(termination_char));
    }
  }
  //Clean buffers
  memset(user_keyrequest_buffer, 0, sizeof(user_keyrequest_buffer));
  memset(base64_username, 0, sizeof(base64_username));
  return 0;
}
Exemplo n.º 15
0
int proc_sign(const ts::wstrings_c & pars)
{
    if (pars.size() < 3) return 0;

    ts::wstr_c arch = pars.get(1); ts::fix_path( arch, FNO_SIMPLIFY );
    ts::wstr_c proc = pars.get(2); ts::fix_path( proc, FNO_SIMPLIFY );

    if (!is_file_exists(arch.as_sptr()))
    {
        Print(FOREGROUND_RED, "arch file not found: %s\n", to_str(arch).cstr()); return 0;
    }
    if (!is_file_exists(proc.as_sptr()))
    {
        Print(FOREGROUND_RED, "proc file not found: %s\n", to_str(proc).cstr()); return 0;
    }
    ts::buf_c b; b.load_from_disk_file(arch);
    int archlen = b.size();
    ts::md5_c md5;
    md5.update(b.data(), b.size()); md5.done();
    ts::abp_c bp;
    b.load_from_disk_file(proc);
    bp.load(b.cstr());

    ts::wstr_c procpath = ts::fn_get_path(proc);
    auto pa = [&]( ts::asptr p ) ->ts::wstr_c
    {
        return ts::fn_join(procpath, to_wstr(bp.get_string(p)));
    };

    b.load_from_disk_file( pa(CONSTASTR("ver")) );
    ts::str_c ver = b.cstr();
    ver.replace_all('/','.').trim();

    ts::str_c ss(CONSTASTR("ver="));
    ss.append( ver );
    ss.append(CONSTASTR("\r\nurl="));

    ts::str_c path = bp.get_string(CONSTASTR("path"));
    path.replace_all(CONSTASTR("%ver%"), ver);
    path.replace_all(CONSTASTR("%https%"), CONSTASTR("https://"));
    path.replace_all(CONSTASTR("%http%"), CONSTASTR("http://"));
    path.appendcvt(ts::fn_get_name_with_ext(arch));


    ss.append(path);

    ss.append(CONSTASTR("\r\nsize="));
    ss.append_as_uint(archlen);
    ss.append(CONSTASTR("\r\nmd5="));
    ss.append_as_hex(md5.result(), 16);

    unsigned char pk[crypto_sign_PUBLICKEYBYTES];
    unsigned char sk[crypto_sign_SECRETKEYBYTES];
    b.clear();
    b.load_from_disk_file( pa(CONSTASTR("sk")) );
    if (b.size() != crypto_sign_SECRETKEYBYTES)
    {
        rebuild:
        crypto_sign_keypair(pk, sk);

        FILE *f = _wfopen(pa(CONSTASTR("sk")), L"wb");
        fwrite(sk, 1, sizeof(sk), f);
        fclose(f);

        ts::str_c spk;
        for(int i=0;i<crypto_sign_PUBLICKEYBYTES;++i)
            spk.append(CONSTASTR("0x")).append_as_hex(pk[i]).append(CONSTASTR(", "));
        spk.trunc_length(2);

        f = _wfopen(pa(CONSTASTR("pk")), L"wb");
        fwrite(spk.cstr(), 1, spk.get_length(), f);
        fclose(f);
    } else
    {
        memcpy(sk, b.data(), crypto_sign_SECRETKEYBYTES);
        crypto_sign_ed25519_sk_to_pk(pk, sk);

        b.load_from_disk_file( pa(CONSTASTR("pk")) );
        ts::token<char> t(b.cstr(), ',');
        int n = 0;
        for(;t; ++t, ++n)
        {
            if (n >= sizeof(pk)) goto rebuild;
            ts::str_c nx(*t);
            nx.trim();
            if (pk[n] != (byte)nx.as_uint())
                goto rebuild;
        }
        if (n < sizeof(pk)) goto rebuild;
    }

    unsigned char sig[crypto_sign_BYTES];
    unsigned long long siglen;
    crypto_sign_detached(sig,&siglen, (const byte *)ss.cstr(), ss.get_length(), sk);

    ss.append(CONSTASTR("\r\nsign="));
    ss.append_as_hex(sig, (int)siglen);

    if (CONSTASTR("github") == bp.get_string(CONSTASTR("wiki")))
    {
        ss.insert(0,CONSTASTR("[begin]\r\n"));
        ss.replace_all(CONSTASTR("\r\n"), CONSTASTR("`<br>\r\n`"));
        ss.replace_all(CONSTASTR("[begin]`"), CONSTASTR("[begin]"));
        ss.append(CONSTASTR("`<br>\r\n[end]<br>\r\n"));
    }

    FILE *f = _wfopen(pa(CONSTASTR("result")), L"wb");
    fwrite(ss.cstr(), 1, ss.get_length(), f);
    fclose(f);


    return 0;
}