void session_init_as_client(session *session,unsigned char *private_key,unsigned char *foreign_public_key) { memcpy(session->foreign_public_key, foreign_public_key, CRYPTO_STREAMBOX_KEY); //let's go ahead and initialize our pk to random if (!private_key) memrandom(session->private_key, CRYPTO_STREAMBOX_KEY); else memcpy(session->private_key,private_key,CRYPTO_STREAMBOX_KEY); }
/* * create a change uid capability */ char* mkcap(char *from, char *to) { uint8_t rand[20]; char *cap; char *key; int nfrom, nto, ncap; uint8_t hash[SHA1dlen]; if(caphashfd < 0) return nil; /* create the capability */ nto = strlen(to); nfrom = strlen(from); ncap = nfrom + 1 + nto + 1 + sizeof(rand)*3 + 1; cap = emalloc(ncap); snprint(cap, ncap, "%s@%s", from, to); memrandom(rand, sizeof(rand)); key = cap+nfrom+1+nto+1; enc64(key, sizeof(rand)*3, rand, sizeof(rand)); /* hash the capability */ hmac_sha1((uint8_t*)cap, strlen(cap), (uint8_t*)key, strlen(key), hash, nil); /* give the kernel the hash */ key[-1] = '@'; if(write(caphashfd, hash, SHA1dlen) < 0){ free(cap); return nil; } return cap; }
int session_server_say_hello_second(session *session, unsigned char *packet, unsigned char *hellopacket) { /** 0-7: SERVER_VERSION (8) 8-23: server nonce (16) */ if (memcmp(hellopacket, CLIENT_VERSION, 8)) return 0; memcpy(session->foreign_public_key, hellopacket+8, CRYPTO_STREAMBOX_KEY); memcpy(session->session_nonce+16, hellopacket+40, 8); memrandom(session->session_nonce, 16); memcpy(packet, SERVER_VERSION, 8); memcpy(packet+8, session->session_nonce, 16); crypto_streambox_init(&session->streambox, session->private_key, session->foreign_public_key, session->session_nonce); return 1; }
void session_client_say_hello_first(session *session, unsigned char *packet) { /**Okay, I am deviating from curvecp protocol here. I pulled this from the mailing list: http://marc.info/?l=curvecp&m=134891707018941&w=4 > - In CurveCP, what is the purpose of Box[0'] in the client hello packet? > Is it to prove right from the start that the client actually knows the > secret key associated with the short-term public key that it announced? Well, it shows that _some_ client knows the secret key. An attacker can replay the same Hello packet later, obtaining another Cookie packet. The server has to compute the S->C' shared secret for the Cookie packet, so there's negligible cost to also using it for the Hello packet. The real reason for the 0 and 0' in the Hello packet is explained in http://curvecp.org/availability.html under "Blind amplification". This doesn't dictate how much of the length is in 0 and how much is in 0', but putting some of it into 0' means that there's space for optional encrypted data in the Hello packet, and putting some of it into 0 means that there's space for optional unencrypted data in the Hello packet. ^ In our case, the 0' stuff is not all that useful. */ /**0-7: CLIENT_VERSION number (8) 8-39: public key (32) 40-47: client-picked nonce (8) */ //todo : anti-amplification? //build 8 bytes of nonce memrandom(session->session_nonce+16, 8); crypto_streambox zerobox; crypto_streambox_init(&zerobox, session->private_key, session->foreign_public_key, session->session_nonce); memcpy(packet, CLIENT_VERSION, 8); memcpy(packet+8, zerobox.public_key, CRYPTO_STREAMBOX_KEY); memcpy(packet+40, session->session_nonce+16, 8); }