static void bcrypt_hash(const char *password, int cost, char* hash) { char salt[16]; if(!RAND_bytes(salt, 16)) ; //we've got a problem char* gen = bcrypt_gensalt("$2y$", cost, salt, 16); strcpy(hash, bcrypt(password, gen)); }
// bcrypt.digest( key, salt ) static int luabcrypt_digest( lua_State *L ) { const char *key = luaL_checkstring( L, 1 ); const char *salt = luaL_checkstring( L, 2 ); char hash[ _PASSWORD_LEN ]; bcrypt( key, salt, hash ); lua_pushstring( L, hash ); return 1; }
// bcrypt.verify( key, digest ) static int luabcrypt_verify( lua_State *L ) { const char *key = luaL_checkstring( L, 1 ); const char *digest = luaL_checkstring( L, 2 ); char encrypted[ _PASSWORD_LEN ]; bcrypt( key, digest, encrypted ); int verified = strncmp( encrypted, digest, _PASSWORD_LEN ) == 0; lua_pushboolean( L, verified ); return 1; }
static int bcrypt_verify(const char *password, const char* hash) { char *ret; ret = bcrypt(password, hash); if(strlen(ret) != strlen(hash)) return 1; int status = 0; int i = 0; for(; i < strlen(ret); i++) status |= (ret[i] ^ hash[i]); return status != 0; }
char * crypt(const char *key, const char *setting) { if (setting[0] == '$') { switch (setting[1]) { case '2': return bcrypt(key, setting); default: errno = EINVAL; return (NULL); } } errno = EINVAL; return (NULL); }
static ERL_NIF_TERM hashpw(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { char pw[1024]; char salt[1024]; char *ret = NULL; (void)memset(&pw, '\0', sizeof(pw)); (void)memset(&salt, '\0', sizeof(salt)); if (enif_get_string(env, argv[0], pw, sizeof(pw), ERL_NIF_LATIN1) < 1) return enif_make_badarg(env); if (enif_get_string(env, argv[1], salt, sizeof(salt), ERL_NIF_LATIN1) < 1) return enif_make_badarg(env); if (NULL == (ret = bcrypt(pw, salt)) || 0 == strcmp(ret, ":")) { return enif_make_badarg(env); } return enif_make_string(env, ret, ERL_NIF_LATIN1); }
static int process_hashpw(ETERM *pid, ETERM *data) { int retval = 0; ETERM *pattern, *pwd, *slt, *pwd_bin, *slt_bin; char password[1024]; char salt[1024]; char encrypted[1024] = { 0 }; (void)memset(&password, '\0', sizeof(password)); (void)memset(&salt, '\0', sizeof(salt)); pattern = erl_format("{Pass, Salt}"); if (erl_match(pattern, data)) { pwd = erl_var_content(pattern, "Pass"); pwd_bin = erl_iolist_to_binary(pwd); slt = erl_var_content(pattern, "Salt"); slt_bin = erl_iolist_to_binary(slt); if (ERL_BIN_SIZE(pwd_bin) > sizeof(password)) { retval = process_reply(pid, CMD_HASHPW, "Password too long"); } else if (ERL_BIN_SIZE(slt_bin) > sizeof(salt)) { retval = process_reply(pid, CMD_HASHPW, "Salt too long"); } else { memcpy(password, ERL_BIN_PTR(pwd_bin), ERL_BIN_SIZE(pwd_bin)); memcpy(salt, ERL_BIN_PTR(slt_bin), ERL_BIN_SIZE(slt_bin)); if (bcrypt(encrypted, password, salt)) { retval = process_reply(pid, CMD_HASHPW, "Invalid salt"); } else { retval = process_reply(pid, CMD_HASHPW, encrypted); } } erl_free_term(pwd); erl_free_term(slt); erl_free_term(pwd_bin); erl_free_term(slt_bin); }; erl_free_term(pattern); return retval; }
/* Given a secret and a salt, generates a salted hash (which you can then store safely). */ static VALUE bc_crypt(VALUE self, VALUE key, VALUE salt) { const char * safeguarded = RSTRING_PTR(key) ? RSTRING_PTR(key) : ""; return rb_str_new2((char *)bcrypt(safeguarded, (char *)RSTRING_PTR(salt))); }
int main(int argc, char** argv) { char salt[_PASSWORD_LEN], tmpl[sizeof("/tmp/htpasswd-XXXXXXXXXX")]; char hash[_PASSWORD_LEN], pass[1024], pass2[1024]; char *line = NULL, *login = NULL, *tok; int c, fd, loginlen, batch = 0; FILE *in = NULL, *out = NULL; const char *file = NULL; size_t linesize = 0; ssize_t linelen; mode_t old_umask; #ifdef __OpenBSD__ if (pledge("stdio rpath wpath cpath flock tmppath tty", NULL) == -1) err(1, "pledge"); #endif while ((c = getopt(argc, argv, "I")) != -1) { switch (c) { case 'I': batch = 1; break; default: usage(); /* NOT REACHED */ break; } } argc -= optind; argv += optind; if (batch) { if (argc == 1) file = argv[0]; else if (argc > 1) usage(); #ifdef __OpenBSD__ else if (pledge("stdio", NULL) == -1) err(1, "pledge"); #endif if ((linelen = getline(&line, &linesize, stdin)) == -1) err(1, "cannot read login:password from stdin"); line[linelen-1] = '\0'; if ((tok = strstr(line, ":")) == NULL) errx(1, "cannot find ':' in input"); *tok++ = '\0'; if ((loginlen = asprintf(&login, "%s:", line)) == -1) err(1, "asprintf"); if (strlcpy(pass, tok, sizeof(pass)) >= sizeof(pass)) errx(1, "password too long"); } else { switch (argc) { case 1: #ifdef __OpenBSD__ if (pledge("stdio tty", NULL) == -1) err(1, "pledge"); #endif if ((loginlen = asprintf(&login, "%s:", argv[0])) == -1) err(1, "asprintf"); break; case 2: file = argv[0]; if ((loginlen = asprintf(&login, "%s:", argv[1])) == -1) err(1, "asprintf"); break; default: usage(); /* NOT REACHED */ break; } if (!readpassphrase("Password: "******"unable to read password"); if (!readpassphrase("Retype Password: "******"unable to read password"); } if (strcmp(pass, pass2) != 0) { explicit_bzero(pass, sizeof(pass)); explicit_bzero(pass2, sizeof(pass2)); errx(1, "passwords don't match"); } explicit_bzero(pass2, sizeof(pass2)); } if (strlcpy(salt, bcrypt_gensalt(8), sizeof(salt)) >= sizeof(salt)) errx(1, "salt too long"); if (strlcpy(hash, bcrypt(pass, salt), sizeof(hash)) >= sizeof(hash)) errx(1, "hash too long"); explicit_bzero(pass, sizeof(pass)); if (file == NULL) printf("%s%s\n", login, hash); else { if ((in = fopen(file, "r+")) == NULL) { if (errno == ENOENT) { old_umask = umask(S_IXUSR| S_IWGRP|S_IRGRP|S_IXGRP| S_IWOTH|S_IROTH|S_IXOTH); if ((out = fopen(file, "w")) == NULL) err(1, "cannot open password file for" " reading or writing"); umask(old_umask); } else err(1, "cannot open password file for" " reading or writing"); } else if (flock(fileno(in), LOCK_EX|LOCK_NB) == -1) errx(1, "cannot lock password file"); /* file already exits, copy content and filter login out */ if (out == NULL) { strlcpy(tmpl, "/tmp/htpasswd-XXXXXXXXXX", sizeof(tmpl)); if ((fd = mkstemp(tmpl)) == -1) err(1, "mkstemp"); if ((out = fdopen(fd, "w+")) == NULL) err(1, "cannot open tempfile"); while ((linelen = getline(&line, &linesize, in)) != -1) { if (strncmp(line, login, loginlen) != 0) { if (fprintf(out, "%s", line) == -1) errx(1, "cannot write to temp " "file"); nag(line); } } } if (fprintf(out, "%s%s\n", login, hash) == -1) errx(1, "cannot write new password hash"); /* file already exists, overwrite it */ if (in != NULL) { if (fseek(in, 0, SEEK_SET) == -1) err(1, "cannot seek in password file"); if (fseek(out, 0, SEEK_SET) == -1) err(1, "cannot seek in temp file"); if (ftruncate(fileno(in), 0) == -1) err(1, "cannot truncate password file"); while ((linelen = getline(&line, &linesize, out)) != -1) if (fprintf(in, "%s", line) == -1) errx(1, "cannot write to password " "file"); if (fclose(in) == EOF) err(1, "cannot close password file"); } if (fclose(out) == EOF) { if (in != NULL) err(1, "cannot close temp file"); else err(1, "cannot close password file"); } if (in != NULL && unlink(tmpl) == -1) err(1, "cannot delete temp file (%s)", tmpl); } if (nagcount >= MAXNAG) warnx("%d more logins not using bcryt.", nagcount - MAXNAG); exit(0); }
/*ARGSUSED4*/ char * crypt_genhash_impl(char *ctbuffer, size_t ctbufflen, const char *plaintext, const char *salt, const char **params) { (void) strlcpy(ctbuffer, bcrypt(plaintext, salt), ctbufflen); return (ctbuffer); }