int main(void) { unsigned char ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES]; unsigned char ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES]; unsigned char curve25519_pk[crypto_scalarmult_curve25519_BYTES]; unsigned char curve25519_pk2[crypto_scalarmult_curve25519_BYTES]; unsigned char curve25519_sk[crypto_scalarmult_curve25519_BYTES]; char curve25519_pk_hex[crypto_scalarmult_curve25519_BYTES * 2 + 1]; char curve25519_sk_hex[crypto_scalarmult_curve25519_BYTES * 2 + 1]; unsigned int i; assert(crypto_sign_ed25519_SEEDBYTES <= crypto_hash_sha512_BYTES); crypto_sign_ed25519_seed_keypair(ed25519_pk, ed25519_skpk, keypair_seed); if (crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) != 0) { printf("conversion failed\n"); } crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk); sodium_bin2hex(curve25519_pk_hex, sizeof curve25519_pk_hex, curve25519_pk, sizeof curve25519_pk); sodium_bin2hex(curve25519_sk_hex, sizeof curve25519_sk_hex, curve25519_sk, sizeof curve25519_sk); printf("curve25519 pk: [%s]\n", curve25519_pk_hex); printf("curve25519 sk: [%s]\n", curve25519_sk_hex); for (i = 0U; i < 500U; i++) { crypto_sign_ed25519_keypair(ed25519_pk, ed25519_skpk); if (crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) != 0) { printf("conversion failed\n"); } crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk); crypto_scalarmult_curve25519_base(curve25519_pk2, curve25519_sk); if (memcmp(curve25519_pk, curve25519_pk2, sizeof curve25519_pk) != 0) { printf("conversion failed\n"); } } sodium_hex2bin(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES, "0000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000", 64, NULL, NULL, NULL); assert(crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) == -1); sodium_hex2bin(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES, "0200000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000", 64, NULL, NULL, NULL); assert(crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) == -1); sodium_hex2bin(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES, "0500000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000", 64, NULL, NULL, NULL); assert(crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) == -1); printf("ok\n"); return 0; }
static size_t lws_gen_server_key_ed25519(struct lws_context *context, uint8_t *buf256, size_t max_len) { uint8_t *p = buf256 + sizeof(key_leadin) - 1; if (max_len < sizeof(key_leadin) - 1 + 32 + sizeof(key_sep) - 1 + 32 + sizeof(key_privl) - 1 + 64 + sizeof(key_trail) - 1) return 0; memcpy(buf256, key_leadin, sizeof(key_leadin) - 1); crypto_sign_ed25519_keypair(context, p, p + 32 + sizeof(key_sep) - 1 + 32 + sizeof(key_privl) - 1); memcpy(p + 32 + sizeof(key_sep) - 1, p, 32); p += 32; memcpy(p, key_sep, sizeof(key_sep) - 1); p += sizeof(key_sep) - 1 + 32; memcpy(p, key_privl, sizeof(key_privl) - 1); p += sizeof(key_privl) - 1 + 64; memcpy(p, key_trail, sizeof(key_trail) - 1); p += sizeof(key_trail) - 1; lwsl_notice("%s: Generated key len %ld\n", __func__, (long)(p - buf256)); return p - buf256; }
int pki_key_generate_ed25519(ssh_key key) { int rc; key->ed25519_privkey = malloc(sizeof (ed25519_privkey)); if (key->ed25519_privkey == NULL) { goto error; } key->ed25519_pubkey = malloc(sizeof (ed25519_pubkey)); if (key->ed25519_pubkey == NULL) { goto error; } rc = crypto_sign_ed25519_keypair(*key->ed25519_pubkey, *key->ed25519_privkey); if (rc != 0) { goto error; } return SSH_OK; error: SAFE_FREE(key->ed25519_privkey); SAFE_FREE(key->ed25519_pubkey); return SSH_ERROR; }
int generate_key(char *secret_key_name, char *public_key_name) { int error = 0; int written; unsigned char public_key[crypto_sign_ed25519_PUBLICKEYBYTES]; unsigned char secret_key[crypto_sign_ed25519_SECRETKEYBYTES]; FILE *public_key_file = NULL; FILE *secret_key_file = NULL; error = crypto_sign_ed25519_keypair(public_key, secret_key); if (error != 0) { fprintf(stderr, "Could not generate key pair\n"); error = -1; goto out; } public_key_file = fopen(public_key_name, "w"); if (public_key_file == NULL) { perror("public key file"); error = -1; goto out; } secret_key_file = fopen(secret_key_name, "w"); if (public_key_file == NULL) { perror("secret key file"); error = -1; goto out; } written = fwrite(public_key, sizeof(public_key), 1, public_key_file); if (written != 1 || ferror(public_key_file) != 0) { perror("writing to public key file"); error = -1; goto out; } written = fwrite(secret_key, sizeof(secret_key), 1, secret_key_file); if (written != 1 || ferror(secret_key_file) != 0) { perror("writing to secret key file"); error = -1; goto out; } #if DEBUG printf("Public key:\n"); print_bytes(public_key, sizeof(public_key)); printf("Secret key:\n"); print_bytes(secret_key, sizeof(secret_key)); #endif out: fclose(public_key_file); fclose(secret_key_file); return error; }
/* * generate two key pairs, one for signing and one for encryption. */ static void generate(const char *pubkeyfile, const char *seckeyfile, int rounds, const char *ident) { struct pubkey pubkey; struct seckey seckey; uint8_t symkey[SYMKEYBYTES]; uint8_t fingerprint[FPLEN]; kdf_allowstdin allowstdin = { 1 }; kdf_confirm confirm = { 1 }; if (!seckeyfile) seckeyfile = gethomefile("seckey"); memset(&pubkey, 0, sizeof(pubkey)); memset(&seckey, 0, sizeof(seckey)); crypto_sign_ed25519_keypair(pubkey.sigkey, seckey.sigkey); crypto_box_keypair(pubkey.enckey, seckey.enckey); randombytes(fingerprint, sizeof(fingerprint)); memcpy(seckey.fingerprint, fingerprint, FPLEN); memcpy(seckey.sigalg, SIGALG, 2); memcpy(seckey.encalg, ENCALG, 2); memcpy(seckey.symalg, SYMALG, 2); memcpy(seckey.kdfalg, KDFALG, 2); seckey.kdfrounds = htonl(rounds); randombytes(seckey.salt, sizeof(seckey.salt)); kdf(seckey.salt, sizeof(seckey.salt), rounds, allowstdin, confirm, symkey, sizeof(symkey)); symencryptmsg(seckey.sigkey, sizeof(seckey.sigkey) + sizeof(seckey.enckey), seckey.box, symkey); explicit_bzero(symkey, sizeof(symkey)); writekeyfile(seckeyfile, "SECRET KEY", &seckey, sizeof(seckey), ident, O_EXCL, 0600); explicit_bzero(&seckey, sizeof(seckey)); memcpy(pubkey.fingerprint, fingerprint, FPLEN); memcpy(pubkey.sigalg, SIGALG, 2); memcpy(pubkey.encalg, ENCALG, 2); if (!pubkeyfile) pubkeyfile = gethomefile("pubkey"); writekeyfile(pubkeyfile, "PUBLIC KEY", &pubkey, sizeof(pubkey), ident, O_EXCL, 0666); }
int main(int argc, char *argv[]) { unsigned char pk[crypto_sign_ed25519_PUBLICKEYBYTES]; unsigned char sk[crypto_sign_ed25519_SECRETKEYBYTES]; if (argc == 2 && argv[1][0] == 'g') { crypto_sign_ed25519_keypair(pk, sk); printf("Public key:\n"); int i; for (i = 0; i < crypto_sign_ed25519_PUBLICKEYBYTES; i++) { printf("%02hhX", pk[i]); } printf("\nSecret key:\n"); for (i = 0; i < crypto_sign_ed25519_SECRETKEYBYTES; i++) { printf("%02hhX", sk[i]); } printf("\n"); } if (argc == 5 && argv[1][0] == 's') { unsigned char *secret_key = hex_string_to_bin(argv[2]); char *data; int size = load_file(argv[3], &data); if (size < 0) goto fail; unsigned long long smlen; char *sm = malloc(size + crypto_sign_ed25519_BYTES * 2); crypto_sign_ed25519(sm, &smlen, data, size, secret_key); if (smlen - size != crypto_sign_ed25519_BYTES) goto fail; FILE *f = fopen(argv[4], "wb"); if (f == NULL) goto fail; memcpy(sm + smlen, sm, crypto_sign_ed25519_BYTES); // Move signature from beginning to end of file. if (fwrite(sm + (smlen - size), 1, smlen, f) != smlen) goto fail; fclose(f); printf("Signed successfully.\n"); } if (argc == 4 && argv[1][0] == 'c') { unsigned char *public_key = hex_string_to_bin(argv[2]); char *data; int size = load_file(argv[3], &data); if (size < 0) goto fail; char *signe = malloc(size + crypto_sign_ed25519_BYTES); memcpy(signe, data + size - crypto_sign_ed25519_BYTES, crypto_sign_ed25519_BYTES); // Move signature from end to beginning of file. memcpy(signe + crypto_sign_ed25519_BYTES, data, size - crypto_sign_ed25519_BYTES); unsigned long long smlen; char *m = malloc(size); unsigned long long mlen; if (crypto_sign_ed25519_open(m, &mlen, signe, size, public_key) == -1) { printf("Failed checking sig.\n"); goto fail; } printf("Checked successfully.\n"); } return 0; fail: printf("FAIL\n"); return 1; }
SODIUM_EXPORT int crypto_sign_ed25519_ref_keypair(unsigned char *pk, unsigned char *sk) { return crypto_sign_ed25519_keypair(pk, sk); }
int cpn_sign_keys_generate(struct cpn_sign_keys *out) { return crypto_sign_ed25519_keypair(out->pk.data, out->sk.data); }
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) { return crypto_sign_ed25519_keypair(pk, sk); }
/* Ensure that server has everything it needs to begin operation. @return -1 on failure, a socket file descriptor on success. */ int server_init(struct init_params * passback_params) { static uint32_t system_init = 0; static uint32_t server_socket = 0; static struct sockaddr_in server_address; if (system_init != 1) { //Init log with the binary name initlog("cmtpd"); print_to_log("cmtpd started", LOG_INFO); //Set working variables char * jail_directory = "/var/cmtp"; char * working_user = "******"; char * config_file = "/etc/cmtpd/cmtpd.conf"; struct config_struct working_config; network_crypto_version = htobe32(crypto_version); if (getdomainname(home_domain, sizeof(home_domain))<0) { perror("getdomainname"); print_to_log("getdomainname failure.", LOG_EMERG); } //Null domain case if (strlen(home_domain)==0) { print_to_log("Domain name null", LOG_EMERG); exit(1); } #ifdef DEBUG //Setting home_domain to hawaii.edu for testing purposes memcpy(home_domain, "hawaii.edu", 11); #endif /*DEBUG*/ //Config file if (parse_config(config_file, &working_config)<0) { print_to_log("Cannot read config file. Proceeding with caution", LOG_ERR); } //Allows caller to know max connections passback_params->max_available_connections = working_config.max_connections; int32_t public_key_descriptor = -1; int32_t private_key_descriptor = -1; //Check for Keys create_verify_dir("/etc/cmtp/"); if ((access("/etc/cmtp/public.key", R_OK)<0)||(access("/etc/cmtp/private.key",R_OK)<0)) { printf("Attempting to create keys\n"); //Key error has occured. At least one of the two keys does not exist. NUKE EVERYTHING!!! (ie. recreate keys). crypto_sign_ed25519_keypair(server_public_key, server_private_key); //print_buffer (server_public_key, 32, "server public key: ", 32, 1); if ((public_key_descriptor=open("/etc/cmtp/public.key", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR))<0) { perror("open"); print_to_log("Error opening public key. Cannot store public key", LOG_ERR); } if (write(public_key_descriptor, &server_public_key, sizeof(server_public_key))<0) { perror("write"); print_to_log("Error writing public key. Cannot store public key", LOG_ERR); } if (close(public_key_descriptor)<0) { perror("close"); print_to_log("Cannot close public key", LOG_ERR); } if ((private_key_descriptor=open("/etc/cmtp/private.key", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR))<0) { perror("open"); print_to_log("Error opening private key. Cannot store public key", LOG_ERR); } if (write(private_key_descriptor, &server_private_key, sizeof(server_private_key))<0) { perror("write"); print_to_log("Error writing private key. Cannot store public key", LOG_ERR); } if (close(private_key_descriptor)<0) { perror("close"); print_to_log("Cannot close private key", LOG_ERR); } } //Read in public and private Keys else if ((access("/etc/cmtp/public.key", R_OK)>=0)&&(access("/etc/cmtp/private.key",R_OK)>=0)) { if ((public_key_descriptor = open("/etc/cmtp/public.key", O_RDONLY))<0) { perror("open"); print_to_log("Cannot open public key. Error, Error!", LOG_CRIT); return -1; } if (read(public_key_descriptor, &server_public_key, sizeof(server_public_key))<0) { perror("read"); print_to_log("Cannot read public key.", LOG_CRIT); return -1; } if (close(public_key_descriptor)<0) { perror("close"); print_to_log("Cannot close public key", LOG_ERR); } if ((private_key_descriptor = open("/etc/cmtp/private.key", O_RDONLY))<0) { perror("open"); print_to_log("Cannot open private key. Error, Error!", LOG_ERR); } if (read(private_key_descriptor, &server_private_key, sizeof(server_private_key))<0) { perror("read"); print_to_log("Cannot read private key.", LOG_CRIT); return -1; } if (close(private_key_descriptor)<0) { perror("close"); print_to_log("Cannot close private key", LOG_ERR); } } if ((create_verify_dir(jail_directory)<0)) { exit(1); } //Configure server socket server_socket = socket(AF_INET, SOCK_STREAM, 0); server_address.sin_port = htobe16(LISTEN_PORT); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htobe32(INADDR_ANY); if (bind(server_socket,(struct sockaddr *)&server_address, sizeof(server_address)) < 0) { print_to_log("Binding to local socket failed. Cannot continue", LOG_EMERG); perror("Bind() on server_socket has failed\n"); return -1; } if (listen(server_socket, 10) < 0) { print_to_log("Listening on local socket has failed. Cannot continue", LOG_EMERG); perror("Listen() on server_socket has failed\n"); return -1; } //Set ownership of /var/cmtp struct passwd * root_user_passwd; root_user_passwd = getpwnam("root"); if (((chown(jail_directory, root_user_passwd->pw_uid, root_user_passwd->pw_gid))==1)) { perror("chown"); print_to_log("chown of working directories failed. Cannot proceed.", LOG_EMERG); exit(1); } if (init_jail(jail_directory)<0) { print_to_log("init_jail returned -1. Cannot proceed", LOG_EMERG); exit(1); } if (enter_jail(jail_directory, working_user)) { print_to_log("enter_jail returned -1. Cannot proceed", LOG_EMERG); exit(1); } system_init = 1; } //Check config files in /etc/cmtp. Parse and load if they do. print_to_log("cmtp init finished.", LOG_INFO); return server_socket; }