Beispiel #1
0
int zmq::curve_server_t::produce_ready (msg_t *msg_)
{
    uint8_t ready_nonce [crypto_box_NONCEBYTES];
    uint8_t ready_plaintext [crypto_box_ZEROBYTES + 256];
    uint8_t ready_box [crypto_box_BOXZEROBYTES + 16 + 256];

    //  Create Box [metadata](S'->C')
    memset (ready_plaintext, 0, crypto_box_ZEROBYTES);
    uint8_t *ptr = ready_plaintext + crypto_box_ZEROBYTES;

    //  Add socket type property
    const char *socket_type = socket_type_string (options.type);
    ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type));

    //  Add identity property
    if (options.type == ZMQ_REQ
    ||  options.type == ZMQ_DEALER
    ||  options.type == ZMQ_ROUTER)
        ptr += add_property (ptr, "Identity", options.identity, options.identity_size);

    const size_t mlen = ptr - ready_plaintext;

    memcpy (ready_nonce, "CurveZMQREADY---", 16);
    memcpy (ready_nonce + 16, &cn_nonce, 8);

    int rc = crypto_box_afternm (ready_box, ready_plaintext,
                                 mlen, ready_nonce, cn_precom);
    zmq_assert (rc == 0);

    rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES);
    errno_assert (rc == 0);

    uint8_t *ready = static_cast <uint8_t *> (msg_->data ());

    memcpy (ready, "\x05READY", 6);
    //  Short nonce, prefixed by "CurveZMQREADY---"
    memcpy (ready + 6, &cn_nonce, 8);
    //  Box [metadata](S'->C')
    memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES,
            mlen - crypto_box_BOXZEROBYTES);

    cn_nonce++;

    return 0;
}
/* Fast encrypt. Depends on enc_key from encrypt_precompute. */
int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
                      uint8_t *plain, uint32_t length, uint8_t *encrypted)
{
    if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0)
        return -1;

    uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0};
    uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES];

    memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.

    crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key);

    if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0)
        return -1;

    /* Unpad the encrypted message. */
    memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
    return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES;
}
Beispiel #3
0
int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, size_t length,
                               uint8_t *encrypted)
{
    if (length == 0 || !secret_key || !nonce || !plain || !encrypted) {
        return -1;
    }

    uint8_t temp_plain[length + crypto_box_ZEROBYTES];
    uint8_t temp_encrypted[length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES];

    memset(temp_plain, 0, crypto_box_ZEROBYTES);
    memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.

    if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0) {
        return -1;
    }

    /* Unpad the encrypted message. */
    memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
    return length + crypto_box_MACBYTES;
}
Beispiel #4
0
// enc_msg = crypto_secretbox(msg, nonce, shared_secret);
static int tweetnacl_crypto_secretbox( lua_State* L )
{
  unsigned int msg_len;
  const char* msg = luaL_checklstring(L,1,&msg_len);
  if(msg_len < 1)
    return luaL_error( L, "len(message)=%d, too short", msg_len);

  unsigned int nonce_len;
  const char* nonce = luaL_checklstring(L,2,&nonce_len);
  if(nonce_len != crypto_box_NONCEBYTES)
    return luaL_error( L, "len(nonce)=%d, should be %d", nonce_len, crypto_box_NONCEBYTES);

  unsigned int secret_len;
  const char* secret = luaL_checklstring(L,3,&secret_len);
  if(secret_len != crypto_box_BEFORENMBYTES)
    return luaL_error( L, "len(secret)=%d, should be %d", secret_len, crypto_box_BEFORENMBYTES);

  unsigned int cmsg_len = msg_len + crypto_box_ZEROBYTES;
  char *cmsg = (char *)c_malloc(cmsg_len);
  if(!cmsg)
    return luaL_error( L, "malloc failed, %d bytes", cmsg_len);

  int i;
  for(i=0;i<crypto_box_ZEROBYTES;i++) cmsg[i] = 0;
  for(;i<cmsg_len;i++) cmsg[i] = msg[i-crypto_box_ZEROBYTES];

  unsigned int emsg_len = cmsg_len;
  char *emsg = (char *)c_malloc(emsg_len);
  if(!emsg)
  {
    c_free(cmsg);
    return luaL_error( L, "malloc failed, %d bytes", emsg_len);
  }

  crypto_box_afternm(emsg, cmsg, cmsg_len, nonce, secret);
  lua_pushlstring(L, emsg+crypto_box_BOXZEROBYTES, emsg_len-crypto_box_BOXZEROBYTES);
  c_free(cmsg);
  c_free(emsg);
  return 1;
}
Beispiel #5
0
ssize_t curve25519_encode(struct curve25519_struct *c, struct curve25519_proto *p,
			  unsigned char *plaintext, size_t size,
			  unsigned char **chipertext)
{
	int ret, i;
	ssize_t done = size;
	struct taia packet_taia;

	spinlock_lock(&c->enc_lock);

	if (unlikely(size > c->enc_buf_size)) {
		spinlock_unlock(&c->enc_lock);
		return -ENOMEM;
	}

	taia_now(&packet_taia);
	taia_pack(p->enonce + NONCE_OFFSET, &packet_taia);

	memset(c->enc_buf, 0, c->enc_buf_size);

	ret = crypto_box_afternm(c->enc_buf, plaintext, size,
				 p->enonce, p->key);
	if (unlikely(ret)) {
		spinlock_unlock(&c->enc_lock);
		return -EIO;
	}

	memcpy(c->enc_buf + crypto_box_boxzerobytes - NONCE_LENGTH,
	       p->enonce + NONCE_OFFSET, NONCE_LENGTH);

	for (i = 0; i < crypto_box_boxzerobytes - NONCE_LENGTH; ++i)
		c->enc_buf[i] = (uint8_t) mt_rand_int32();

	(*chipertext) = c->enc_buf;

	spinlock_unlock(&c->enc_lock);

	return done;
}
Beispiel #6
0
static int _handle_initiate (struct curvecpr_server *server, struct curvecpr_session *s, void *priv, const struct curvecpr_packet_initiate *p, const unsigned char *buf, size_t num)
{
    const struct curvecpr_server_cf *cf = &server->cf;

    unsigned char nonce[24];
    unsigned char data[sizeof(struct curvecpr_packet_initiate_box) + 640];

    if (s != NULL) {
        /* Update existing client. */
        crypto_uint64 unpacked_nonce = curvecpr_bytes_unpack_uint64(p->nonce);
        if (unpacked_nonce <= s->their_session_nonce)
            return -EINVAL;

        curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16);
        curvecpr_bytes_copy(nonce + 16, p->nonce, 8);

        curvecpr_bytes_zero(data, 16);
        curvecpr_bytes_copy(data + 16, buf, num);

        if (crypto_box_open_afternm(data, data, num + 16, nonce, s->my_session_their_session_key))
            return -EINVAL;

        s->their_session_nonce = unpacked_nonce;
        curvecpr_session_set_priv(s, priv);

        if (cf->ops.recv(server, s, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box)))
            return -EINVAL;

        return 0;
    } else {
        struct curvecpr_session s_new, *s_new_stored;
        const struct curvecpr_packet_initiate_box *p_box;

        /* Register new client. */
        curvecpr_bytes_copy(nonce, "minute-k", 8);
        curvecpr_bytes_copy(nonce + 8, p->cookie, 16);

        /* We can reuse data; the cookie will fit into it. */
        curvecpr_bytes_zero(data, 16);
        curvecpr_bytes_copy(data + 16, p->cookie + 16, 80);

        /* Validate cookie. */
        if (crypto_secretbox_open(data, data, 96, nonce, server->my_temporal_key)) {
            curvecpr_bytes_zero(data, 16);
            curvecpr_bytes_copy(data + 16, p->cookie + 16, 80);
            if (crypto_secretbox_open(data, data, 96, nonce, server->my_last_temporal_key))
                return -EINVAL;
        }

        if (!curvecpr_bytes_equal(p->client_session_pk, data + 32, 32))
            return -EINVAL;

        /* Cookie is valid; set up keys. */
        curvecpr_session_new(&s_new);

        curvecpr_bytes_copy(s_new.their_session_pk, data + 32, 32);
        curvecpr_bytes_copy(s_new.my_session_sk, data + 64, 32);

        crypto_box_beforenm(s_new.my_session_their_session_key, s_new.their_session_pk, s_new.my_session_sk);

        curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16);
        curvecpr_bytes_copy(nonce + 16, p->nonce, 8);

        curvecpr_bytes_zero(data, 16);
        curvecpr_bytes_copy(data + 16, buf, num);

        if (crypto_box_open_afternm(data, data, num + 16, nonce, s_new.my_session_their_session_key))
            return -EINVAL;

        p_box = (struct curvecpr_packet_initiate_box *)data;

        /* Attempt to validate this client. */
        {
            unsigned char vouch[64];

            curvecpr_bytes_copy(s_new.their_global_pk, p_box->client_global_pk, 32);
            crypto_box_beforenm(s_new.my_global_their_global_key, s_new.their_global_pk, cf->my_global_sk);

            curvecpr_bytes_copy(nonce, "CurveCPV", 8);
            curvecpr_bytes_copy(nonce + 8, p_box->nonce, 16);

            curvecpr_bytes_zero(vouch, 16);
            curvecpr_bytes_copy(vouch + 16, p_box->vouch, 48);

            if (crypto_box_afternm(vouch, vouch, 64, nonce, s_new.my_global_their_global_key))
                return -EINVAL;

            if (!curvecpr_bytes_equal(vouch + 32, s_new.their_session_pk, 32))
                return -EINVAL;
        }

        /* All good, we can go ahead and submit the client for registration. */
        s_new.their_session_nonce = curvecpr_bytes_unpack_uint64(p->nonce);
        curvecpr_bytes_copy(s_new.my_domain_name, p_box->server_domain_name, 256);
        curvecpr_session_set_priv(&s_new, priv);

        if (cf->ops.put_session(server, &s_new, &s_new_stored))
            return -EINVAL; /* This can fail for a variety of reasons that are up to
                               the delegate to determine, but two typical ones will be
                               too many connections or an invalid domain name. */

        /* Now the session is registered; we can send the encapsulated message. */
        if (cf->ops.recv(server, s_new_stored, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box)))
            return -EINVAL;

        return 0;
    }
}
Beispiel #7
0
static int _handle_hello (struct curvecpr_server *server, void *priv, const struct curvecpr_packet_hello *p)
{
    const struct curvecpr_server_cf *cf = &server->cf;
    struct curvecpr_session s; /* Used only as a temporary store to make what we're doing
                                  more clear. */

    unsigned char nonce[24];
    unsigned char data[96] = { 0 };

    /* Dummy initialization. */
    curvecpr_session_new(&s);
    curvecpr_session_set_priv(&s, priv);

    /* Verify initial connection parameters. */
    curvecpr_bytes_copy(s.their_session_pk, p->client_session_pk, 32);
    crypto_box_beforenm(s.my_global_their_session_key, s.their_session_pk, cf->my_global_sk);

    curvecpr_bytes_copy(nonce, "CurveCP-client-H", 16);
    curvecpr_bytes_copy(nonce + 16, p->nonce, 8);

    curvecpr_bytes_copy(data + 16, p->box, 80);
    if (crypto_box_open_afternm(data, data, 96, nonce, s.my_global_their_session_key))
        return -EINVAL;

    /* Set up session keys. */
    crypto_box_keypair(s.my_session_pk, s.my_session_sk);

    /* Prepare to send a cookie packet. */
    {
        struct curvecpr_packet_cookie po;
        struct curvecpr_packet_cookie_box po_box;

        curvecpr_bytes_zero(po_box._, 32);
        curvecpr_bytes_copy(po_box.server_session_pk, s.my_session_pk, 32);

        /* Generate the cookie. */
        curvecpr_bytes_zero(po_box.cookie, 32);
        curvecpr_bytes_copy(po_box.cookie + 32, s.their_session_pk, 32);
        curvecpr_bytes_copy(po_box.cookie + 64, s.my_session_sk, 32);

        /* Encrypt the cookie with our global nonce and temporary key. */
        curvecpr_bytes_copy(nonce, "minute-k", 8);
        if (cf->ops.next_nonce(server, nonce + 8, 16))
            return -EINVAL;

        crypto_secretbox(po_box.cookie, po_box.cookie, 96, nonce, server->my_temporal_key);
        curvecpr_bytes_copy(po_box.cookie, nonce + 8, 16);

        /* Now encrypt the whole box. */
        curvecpr_bytes_copy(nonce, "CurveCPK", 8);

        crypto_box_afternm((unsigned char *)&po_box, (const unsigned char *)&po_box, sizeof(struct curvecpr_packet_cookie_box), nonce, s.my_global_their_session_key);

        /* Build the rest of the packet. */
        curvecpr_bytes_copy(po.id, "RL3aNMXK", 8);
        curvecpr_bytes_copy(po.client_extension, p->client_extension, 16);
        curvecpr_bytes_copy(po.server_extension, cf->my_extension, 16);
        curvecpr_bytes_copy(po.nonce, nonce + 8, 16);
        curvecpr_bytes_copy(po.box, (const unsigned char *)&po_box + 16, 144);

        if (cf->ops.send(server, &s, (const unsigned char *)&po, sizeof(struct curvecpr_packet_cookie)))
            return -EINVAL;
    }

    return 0;
}
Beispiel #8
0
int main(int argc,char **argv)
{
  long long hellopackets;
  long long r;
  long long nextaction;

  signal(SIGPIPE,SIG_IGN);

  if (!argv[0]) die_usage(0);
  for (;;) {
    char *x;
    if (!argv[1]) break;
    if (argv[1][0] != '-') break;
    x = *++argv;
    if (x[0] == '-' && x[1] == 0) break;
    if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
    while (*++x) {
      if (*x == 'q') { flagverbose = 0; continue; }
      if (*x == 'Q') { flagverbose = 1; continue; }
      if (*x == 'v') { if (flagverbose == 2) flagverbose = 3; else flagverbose = 2; continue; }
      if (*x == 'c') {
        if (x[1]) { keydir = x + 1; break; }
        if (argv[1]) { keydir = *++argv; break; }
      }
      die_usage(0);
    }
  }
  if (!nameparse(servername,*++argv)) die_usage("sname must be at most 255 bytes, at most 63 bytes between dots");
  if (!hexparse(serverlongtermpk,32,*++argv)) die_usage("pk must be exactly 64 hex characters");
  if (!multiipparse(serverip,*++argv)) die_usage("ip must be a comma-separated series of IPv4 addresses");
  if (!portparse(serverport,*++argv)) die_usage("port must be an integer between 0 and 65535");
  if (!hexparse(serverextension,16,*++argv)) die_usage("ext must be exactly 32 hex characters");
  if (!*++argv) die_usage("missing prog");

  for (;;) {
    r = open_read("/dev/null");
    if (r == -1) die_fatal("unable to open /dev/null",0,0);
    if (r > 9) { close(r); break; }
  }

  if (keydir) {
    fdwd = open_cwd();
    if (fdwd == -1) die_fatal("unable to open current working directory",0,0);
    if (chdir(keydir) == -1) die_fatal("unable to change to directory",keydir,0);
    if (load("publickey",clientlongtermpk,sizeof clientlongtermpk) == -1) die_fatal("unable to read public key from",keydir,0);
    if (load(".expertsonly/secretkey",clientlongtermsk,sizeof clientlongtermsk) == -1) die_fatal("unable to read secret key from",keydir,0);
  } else {
    crypto_box_keypair(clientlongtermpk,clientlongtermsk);
  }

  crypto_box_keypair(clientshorttermpk,clientshorttermsk);
  clientshorttermnonce = randommod(281474976710656LL);
  crypto_box_beforenm(clientshortserverlong,serverlongtermpk,clientshorttermsk);
  crypto_box_beforenm(clientlongserverlong,serverlongtermpk,clientlongtermsk);

  udpfd = socket_udp();
  if (udpfd == -1) die_fatal("unable to create socket",0,0);

  for (hellopackets = 0;hellopackets < NUMIP;++hellopackets) {
    recent = nanoseconds();

    /* send a Hello packet: */

    clientextension_init();

    clientshorttermnonce_update();
    byte_copy(nonce,16,"CurveCP-client-H");
    uint64_pack(nonce + 16,clientshorttermnonce);

    byte_copy(packet,8,"QvnQ5XlH");
    byte_copy(packet + 8,16,serverextension);
    byte_copy(packet + 24,16,clientextension);
    byte_copy(packet + 40,32,clientshorttermpk);
    byte_copy(packet + 72,64,allzero);
    byte_copy(packet + 136,8,nonce + 16);
    crypto_box_afternm(text,allzero,96,nonce,clientshortserverlong);
    byte_copy(packet + 144,80,text + 16);

    socket_send(udpfd,packet,224,serverip + 4 * hellopackets,serverport);

    nextaction = recent + hellowait[hellopackets] + randommod(hellowait[hellopackets]);

    for (;;) {
      long long timeout = nextaction - recent;
      if (timeout <= 0) break;
      p[0].fd = udpfd;
      p[0].events = POLLIN;
      if (poll(p,1,timeout / 1000000 + 1) < 0) p[0].revents = 0;

      do { /* try receiving a Cookie packet: */
        if (!p[0].revents) break;
        r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport);
        if (r != 200) break;
        if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) &
              byte_isequal(packetport,2,serverport) &
              byte_isequal(packet,8,"RL3aNMXK") &
              byte_isequal(packet + 8,16,clientextension) &
              byte_isequal(packet + 24,16,serverextension)
           )) break;
        byte_copy(nonce,8,"CurveCPK");
        byte_copy(nonce + 8,16,packet + 40);
        byte_zero(text,16);
        byte_copy(text + 16,144,packet + 56);
        if (crypto_box_open_afternm(text,text,160,nonce,clientshortserverlong)) break;
        byte_copy(servershorttermpk,32,text + 32);
        byte_copy(servercookie,96,text + 64);
        byte_copy(serverip,4,serverip + 4 * hellopackets);
        goto receivedcookie;
      } while (0);

      recent = nanoseconds();
    }
  }

  errno = ETIMEDOUT; die_fatal("no response from server",0,0);

  receivedcookie:

  crypto_box_beforenm(clientshortservershort,servershorttermpk,clientshorttermsk);

  byte_copy(nonce,8,"CurveCPV");
  if (keydir) {
    if (safenonce(nonce + 8,0) == -1) die_fatal("nonce-generation disaster",0,0);
  } else {
    randombytes(nonce + 8,16);
  }

  byte_zero(text,32);
  byte_copy(text + 32,32,clientshorttermpk);
  crypto_box_afternm(text,text,64,nonce,clientlongserverlong);
  byte_copy(vouch,16,nonce + 8);
  byte_copy(vouch + 16,48,text + 16);

  /* server is responding, so start child: */

  if (open_pipe(tochild) == -1) die_fatal("unable to create pipe",0,0);
  if (open_pipe(fromchild) == -1) die_fatal("unable to create pipe",0,0);

  child = fork();
  if (child == -1) die_fatal("unable to fork",0,0);
  if (child == 0) {
    if (keydir) if (fchdir(fdwd) == -1) die_fatal("unable to chdir to original directory",0,0);
    close(8);
    if (dup(tochild[0]) != 8) die_fatal("unable to dup",0,0);
    close(9);
    if (dup(fromchild[1]) != 9) die_fatal("unable to dup",0,0);
    /* XXX: set up environment variables */
    signal(SIGPIPE,SIG_DFL);
    execvp(*argv,argv);
    die_fatal("unable to run",*argv,0);
  }

  close(fromchild[1]);
  close(tochild[0]);


  for (;;) {
    p[0].fd = udpfd;
    p[0].events = POLLIN;
    p[1].fd = fromchild[0];
    p[1].events = POLLIN;

    if (poll(p,2,-1) < 0) {
      p[0].revents = 0;
      p[1].revents = 0;
    }

    do { /* try receiving a Message packet: */
      if (!p[0].revents) break;
      r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport);
      if (r < 80) break;
      if (r > 1152) break;
      if (r & 15) break;
      packetnonce = uint64_unpack(packet + 40);
      if (flagreceivedmessage && packetnonce <= receivednonce) break;
      if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) &
            byte_isequal(packetport,2,serverport) &
            byte_isequal(packet,8,"RL3aNMXM") &
            byte_isequal(packet + 8,16,clientextension) &
            byte_isequal(packet + 24,16,serverextension)
         )) break;
      byte_copy(nonce,16,"CurveCP-server-M");
      byte_copy(nonce + 16,8,packet + 40);
      byte_zero(text,16);
      byte_copy(text + 16,r - 48,packet + 48);
      if (crypto_box_open_afternm(text,text,r - 32,nonce,clientshortservershort)) break;

      if (!flagreceivedmessage) {
        flagreceivedmessage = 1;
	randombytes(clientlongtermpk,sizeof clientlongtermpk);
	randombytes(vouch,sizeof vouch);
	randombytes(servername,sizeof servername);
	randombytes(servercookie,sizeof servercookie);
      }

      receivednonce = packetnonce;
      text[31] = (r - 64) >> 4;
      /* child is responsible for reading all data immediately, so we won't block: */
      if (writeall(tochild[1],text + 31,r - 63) == -1) goto done;
    } while (0);

    do { /* try receiving data from child: */
      long long i;
      if (!p[1].revents) break;
      r = read(fromchild[0],childbuf,sizeof childbuf);
      if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break;
      if (r <= 0) goto done;
      childbuflen = r;
      for (i = 0;i < childbuflen;++i) {
	if (childmessagelen < 0) goto done;
	if (childmessagelen >= sizeof childmessage) goto done;
        childmessage[childmessagelen++] = childbuf[i];
	if (childmessage[0] & 128) goto done;
	if (childmessagelen == 1 + 16 * (unsigned long long) childmessage[0]) {
	  clientextension_init();
	  clientshorttermnonce_update();
          uint64_pack(nonce + 16,clientshorttermnonce);
	  if (flagreceivedmessage) {
	    r = childmessagelen - 1;
	    if (r < 16) goto done;
	    if (r > 1088) goto done;
            byte_copy(nonce,16,"CurveCP-client-M");
	    byte_zero(text,32);
	    byte_copy(text + 32,r,childmessage + 1);
	    crypto_box_afternm(text,text,r + 32,nonce,clientshortservershort);
	    byte_copy(packet,8,"QvnQ5XlM");
	    byte_copy(packet + 8,16,serverextension);
	    byte_copy(packet + 24,16,clientextension);
	    byte_copy(packet + 40,32,clientshorttermpk);
	    byte_copy(packet + 72,8,nonce + 16);
	    byte_copy(packet + 80,r + 16,text + 16);
            socket_send(udpfd,packet,r + 96,serverip,serverport);
	  } else {
	    r = childmessagelen - 1;
	    if (r < 16) goto done;
	    if (r > 640) goto done;
	    byte_copy(nonce,16,"CurveCP-client-I");
	    byte_zero(text,32);
	    byte_copy(text + 32,32,clientlongtermpk);
	    byte_copy(text + 64,64,vouch);
	    byte_copy(text + 128,256,servername);
	    byte_copy(text + 384,r,childmessage + 1);
	    crypto_box_afternm(text,text,r + 384,nonce,clientshortservershort);
	    byte_copy(packet,8,"QvnQ5XlI");
	    byte_copy(packet + 8,16,serverextension);
	    byte_copy(packet + 24,16,clientextension);
	    byte_copy(packet + 40,32,clientshorttermpk);
	    byte_copy(packet + 72,96,servercookie);
	    byte_copy(packet + 168,8,nonce + 16);
	    byte_copy(packet + 176,r + 368,text + 16);
            socket_send(udpfd,packet,r + 544,serverip,serverport);
	  }
	  childmessagelen = 0;
	}
      }
    } while (0);
  }


  done:

  do {
    r = waitpid(child,&childstatus,0);
  } while (r == -1 && errno == EINTR);

  if (!WIFEXITED(childstatus)) { errno = 0; die_fatal("process killed by signal",0,0); }
  return WEXITSTATUS(childstatus);
}
Beispiel #9
0
int main(void)
{
    unsigned char k[crypto_box_BEFORENMBYTES];
    int i;
    int ret;

    ret = crypto_box(c, m, 163, nonce, bobpk, alicesk);
    assert(ret == 0);
    for (i = 16; i < 163; ++i) {
        printf(",0x%02x", (unsigned int)c[i]);
        if (i % 8 == 7)
            printf("\n");
    }
    printf("\n");

    ret = crypto_box(c, m, 163, nonce, small_order_p, alicesk);
    assert(ret == -1);

    memset(c, 0, sizeof c);

    ret = crypto_box_beforenm(k, bobpk, alicesk);
    assert(ret == 0);
    crypto_box_afternm(c, m, 163, nonce, k);
    for (i = 16; i < 163; ++i) {
        printf(",0x%02x", (unsigned int)c[i]);
        if (i % 8 == 7)
            printf("\n");
    }
    printf("\n");

    ret = crypto_box_beforenm(k, small_order_p, alicesk);
    assert(ret == -1);

    assert(crypto_box_seedbytes() > 0U);
    assert(crypto_box_publickeybytes() > 0U);
    assert(crypto_box_secretkeybytes() > 0U);
    assert(crypto_box_beforenmbytes() > 0U);
    assert(crypto_box_noncebytes() > 0U);
    assert(crypto_box_zerobytes() > 0U);
    assert(crypto_box_boxzerobytes() > 0U);
    assert(crypto_box_macbytes() > 0U);
    assert(strcmp(crypto_box_primitive(), "curve25519xsalsa20poly1305") == 0);
    assert(crypto_box_curve25519xsalsa20poly1305_seedbytes()
           == crypto_box_seedbytes());
    assert(crypto_box_curve25519xsalsa20poly1305_publickeybytes()
           == crypto_box_publickeybytes());
    assert(crypto_box_curve25519xsalsa20poly1305_secretkeybytes()
           == crypto_box_secretkeybytes());
    assert(crypto_box_curve25519xsalsa20poly1305_beforenmbytes()
           == crypto_box_beforenmbytes());
    assert(crypto_box_curve25519xsalsa20poly1305_noncebytes()
           == crypto_box_noncebytes());
    assert(crypto_box_curve25519xsalsa20poly1305_zerobytes()
           == crypto_box_zerobytes());
    assert(crypto_box_curve25519xsalsa20poly1305_boxzerobytes()
           == crypto_box_boxzerobytes());
    assert(crypto_box_curve25519xsalsa20poly1305_macbytes()
           == crypto_box_macbytes());

    return 0;
}
Beispiel #10
0
void functional_crypto(UNUSED(void **state))
{
  unsigned char nonce[crypto_box_NONCEBYTES];
  unsigned char initiatenonce[crypto_box_NONCEBYTES];
  unsigned char hellopacket[192] = {0};
  unsigned char initiatepacket[256] = {0};
  unsigned char messagepacket[120];
  unsigned char messagepacketout[120] = {0};
  unsigned char allzeroboxed[96] = {0};
  unsigned char initiatebox[160] = {0};
  unsigned char pubkeybox[96] = {0};
  unsigned char lengthbox[40] = {0};
  uint64_t plaintextlen;
  uint64_t readlen;
  outputstream write;

  connect_to_db();

  wrap_crypto_write = false;

  assert_int_equal(0, filesystem_load(".keys/server-long-term.pub",
      serverlongtermpk, sizeof serverlongtermpk));

  cc.nonce = (uint64_t) randommod(281474976710656LL);

  if (!ISODD(cc.nonce)) {
    cc.nonce++;
  }

  cc.receivednonce = 0;
  cc.state = TUNNEL_INITIAL;

  memcpy(nonce, "splonebox-client", 16);
  uint64_pack(nonce + 16, cc.nonce);

  /* pack hello packet */
  memcpy(hellopacket, "oqQN2kaH", 8);
  /* pack compressed nonce */
  memcpy(hellopacket + 104, nonce + 16, 8);

  /* generate client ephemeral keys */
  if (crypto_box_keypair(clientlongtermpk, clientlongtermsk) != 0)
    return;
  /* generate client ephemeral keys */
  if (crypto_box_keypair(clientshorttermpk, clientshorttermsk) != 0)
    return;

  memcpy(hellopacket + 8, clientshorttermpk, 32);

  assert_int_equal(0, crypto_box(allzeroboxed, allzeroboxed, 96, nonce,
      serverlongtermpk, clientshorttermsk));

  memcpy(hellopacket + 112, allzeroboxed + 16, 80);

  crypto_init();

  /* positiv test */
  assert_int_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write));

  /* wrong identifier */
  memcpy(hellopacket, "deadbeef", 8);
  assert_int_not_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write));
  memcpy(hellopacket, "oqQN2kaH", 8);

  /* wrong nonce */
  cc.receivednonce = cc.nonce + 1;
  assert_int_not_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write));
  cc.receivednonce = 0;

  /* wrong pubkey */
  memset(hellopacket + 8, '0', 32);
  assert_int_not_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write));
  memcpy(hellopacket + 8, clientshorttermpk, 32);

  assert_int_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write));

  /* crypto_recv_initiate() test */

  /* pack initiate packet */
  memcpy(initiatepacket, "oqQN2kaI", 8);
  memcpy(initiatepacket + 8, cookie, 96);
  /* pack compressed nonce */
  memcpy(initiatepacket + 104, nonce + 16, 8);

  memcpy(initiatebox + 32, clientlongtermpk, 32);
  randombytes(initiatebox + 64, 16);
  memcpy(initiatenonce, "splonePV", 8);
  memcpy(initiatenonce + 8, initiatebox + 64, 16);

  memcpy(pubkeybox + 32, clientshorttermpk, 32);
  memcpy(pubkeybox + 64, servershorttermpk, 32);

  assert_int_equal(0, crypto_box(pubkeybox, pubkeybox, 96, initiatenonce,
      serverlongtermpk, clientlongtermsk));

  memcpy(initiatebox + 80, pubkeybox + 16, 80);

  assert_int_equal(0, crypto_box(initiatebox, initiatebox, 160, nonce,
      servershorttermpk, clientshorttermsk));

  memcpy(initiatepacket + 112, initiatebox + 16, 144);

  /* without valid certificate */
  assert_int_not_equal(0, crypto_recv_initiate(&cc, initiatepacket));

  /* all plugins are allowed to connect */
  db_authorized_set_whitelist_all();
  assert_int_equal(0, crypto_recv_initiate(&cc, initiatepacket));

  /* crypto_write() test */
  assert_int_equal(0, crypto_write(&cc, (char*) allzeroboxed,
      sizeof(allzeroboxed), &write));

  /* crypto_read() test */

  /* pack message packet */
  memcpy(messagepacket, "oqQN2kaM", 8);

  /* pack compressed nonce */
  memcpy(nonce, "splonebox-client", 16);
  uint64_pack(nonce + 16, cc.nonce);
  memcpy(messagepacket + 8, nonce + 16, 8);

  uint64_pack(lengthbox + 32, 120);

  assert_int_equal(0, crypto_box(lengthbox, lengthbox, 40, nonce,
      servershorttermpk, clientshorttermsk));

  memcpy(messagepacket + 16, lengthbox + 16, 24);

  uint64_pack(nonce + 16, cc.nonce + 2);

  memset(allzeroboxed, 0, 96);
  assert_int_equal(0, crypto_box_afternm(allzeroboxed, allzeroboxed, 96, nonce,
      cc.clientshortservershort));

  memcpy(messagepacket + 40, allzeroboxed + 16, 80);

  assert_int_equal(0, crypto_verify_header(&cc, messagepacket, &readlen));

  assert_int_equal(0, crypto_read(&cc, messagepacket, (char*)messagepacketout,
      readlen, &plaintextlen));

  db_close();
}