int ccencrypt_init(ccrypt_stream_t *b, char *key) { word32 keyblock[8]; ccrypt_state_t *st; st = malloc(sizeof(ccrypt_state_t)); if (st == NULL) { b->state = NULL; return -1; } b->state = (void *)st; /* generate the roundkey */ hashstring(key, keyblock); xrijndaelKeySched(keyblock, 256, 256, &st->rkk); /* make a nonce */ make_nonce(st->buf); /* mark the nonce with a "magic number". */ strncpy((char *)st->buf, MAGIC, 4); /* encrypt the nonce with the given key */ xrijndaelEncrypt(st->buf, &st->rkk); /* IV is now contained in st->buf. Initialize rest of the state. */ st->iv = 1; st->bufindex = 0; /* initially use bufsize to count iv bytes output */ return 0; }
svn_error_t *svn_ra_svn_cram_server(svn_ra_svn_conn_t *conn, apr_pool_t *pool, svn_config_t *pwdb, const char **user, svn_boolean_t *success) { apr_status_t status; apr_uint64_t nonce; char hostbuf[APRMAXHOSTLEN + 1]; unsigned char cdigest[APR_MD5_DIGESTSIZE], sdigest[APR_MD5_DIGESTSIZE]; const char *challenge, *sep, *password; svn_ra_svn_item_t *item; svn_string_t *resp; *success = FALSE; /* Send a challenge. */ status = make_nonce(&nonce); if (!status) status = apr_gethostname(hostbuf, sizeof(hostbuf), pool); if (status) return fail(conn, pool, "Internal server error in authentication"); challenge = apr_psprintf(pool, "<%" APR_UINT64_T_FMT ".%" APR_TIME_T_FMT "@%s>", nonce, apr_time_now(), hostbuf); SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(c)", "step", challenge)); /* Read the client's response and decode it into *user and cdigest. */ SVN_ERR(svn_ra_svn__read_item(conn, pool, &item)); if (item->kind != SVN_RA_SVN_STRING) /* Very wrong; don't report failure */ return SVN_NO_ERROR; resp = item->u.string; sep = strrchr(resp->data, ' '); if (!sep || resp->len - (sep + 1 - resp->data) != APR_MD5_DIGESTSIZE * 2 || !hex_decode(cdigest, sep + 1)) return fail(conn, pool, "Malformed client response in authentication"); *user = apr_pstrmemdup(pool, resp->data, sep - resp->data); /* Verify the digest against the password in pwfile. */ svn_config_get(pwdb, &password, SVN_CONFIG_SECTION_USERS, *user, NULL); if (!password) return fail(conn, pool, "Username not found"); compute_digest(sdigest, challenge, password); if (memcmp(cdigest, sdigest, sizeof(sdigest)) != 0) return fail(conn, pool, "Password incorrect"); *success = TRUE; return svn_ra_svn__write_tuple(conn, pool, "w()", "success"); }
/* Check that a nonce is one that we issued, and that the response is what is expected. This doesn't do any checking against the lifetime of the nonce. */ int http_digest_check_credentials(const char *username, const char *realm, const char *password, const char *method, const struct http_credentials *credentials) { char response_hex[MD5_DIGEST_LENGTH * 2 + 1]; struct timeval tv; char *nonce; if (credentials->scheme != AUTH_DIGEST || credentials->u.digest.username == NULL || credentials->u.digest.realm == NULL || credentials->u.digest.nonce == NULL || credentials->u.digest.uri == NULL || credentials->u.digest.response == NULL) { return 0; } if (credentials->u.digest.qop != QOP_NONE && credentials->u.digest.qop != QOP_AUTH) return 0; if (credentials->u.digest.qop == QOP_AUTH && (credentials->u.digest.nc == NULL || credentials->u.digest.cnonce == NULL)) { return 0; } if (strcmp(username, credentials->u.digest.username) != 0) return 0; if (strcmp(realm, credentials->u.digest.realm) != 0) return 0; if (http_digest_nonce_time(credentials->u.digest.nonce, &tv) == -1) return 0; nonce = make_nonce(&tv); if (strcmp(nonce, credentials->u.digest.nonce) != 0) { /* We could not have handed out this nonce. */ free(nonce); return 0; } free(nonce); make_response(response_hex, credentials->u.digest.username, realm, password, method, credentials->u.digest.uri, credentials->u.digest.nonce, credentials->u.digest.qop, credentials->u.digest.nc, credentials->u.digest.cnonce); return strcmp(response_hex, credentials->u.digest.response) == 0; }
/* encryption */ int ccencrypt(reader *r, writer *w, char *keyword) { word32 state[8]; word8 *statec = (word8 *)state; roundkey rkk; word32 key[8]; int i, c, cc; int st; /* generate the roundkey */ hashstring(keyword, key); xrijndaelKeySched(key, 256, 256, &rkk); /* make a nonce */ make_nonce(state); /* mark the nonce with a "magic number". */ strncpy(statec, MAGIC, 4); /* encrypt the nonce with the given keyword */ xrijndaelEncrypt(state, &rkk); /* write the seed (header) */ for (i=0; i<32; i++) { st = w->bputc(statec[i], w); if (st<0) return -1; } /* encrypt the body of the stream */ c = r->bgetc(r); while (c != EOF) { xrijndaelEncrypt(state, &rkk); for (i=0; i<32 && c != EOF; i++) { cc = c ^ statec[i]; statec[i] = cc; st = w->bputc(cc, w); if (st<0) return -1; c = r->bgetc(r); } } if (errno) return -1; return w->beof(w); }
char *http_digest_proxy_authenticate(const char *realm, int stale) { char *buf = NULL; size_t size = 0, offset = 0; struct timeval tv; char *nonce; if (gettimeofday(&tv, NULL) == -1) return NULL; strbuf_append_str(&buf, &size, &offset, "Digest realm="); append_quoted_string(&buf, &size, &offset, realm); nonce = make_nonce(&tv); strbuf_append_str(&buf, &size, &offset, ", nonce="); append_quoted_string(&buf, &size, &offset, nonce); free(nonce); strbuf_append_str(&buf, &size, &offset, ", qop=\"auth\""); if (stale) strbuf_append_str(&buf, &size, &offset, ", stale=true"); return buf; }
static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) { if (!config.password) return 0; if (!*nonce) { *nonce = make_nonce(); goto authenticate; } char *hdr = msg_get_header(req, "Authorization"); if (!hdr || strncmp(hdr, "Digest ", 7)) goto authenticate; char *realm = strstr(hdr, "realm=\""); char *username = strstr(hdr, "username=\""); char *response = strstr(hdr, "response=\""); char *uri = strstr(hdr, "uri=\""); if (!realm || !username || !response || !uri) goto authenticate; char *quote; realm = strchr(realm, '"') + 1; if (!(quote = strchr(realm, '"'))) goto authenticate; *quote = 0; username = strchr(username, '"') + 1; if (!(quote = strchr(username, '"'))) goto authenticate; *quote = 0; response = strchr(response, '"') + 1; if (!(quote = strchr(response, '"'))) goto authenticate; *quote = 0; uri = strchr(uri, '"') + 1; if (!(quote = strchr(uri, '"'))) goto authenticate; *quote = 0; uint8_t digest_urp[16], digest_mu[16], digest_total[16]; MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, username, strlen(username)); MD5_Update(&ctx, ":", 1); MD5_Update(&ctx, realm, strlen(realm)); MD5_Update(&ctx, ":", 1); MD5_Update(&ctx, config.password, strlen(config.password)); MD5_Final(digest_urp, &ctx); MD5_Init(&ctx); MD5_Update(&ctx, req->method, strlen(req->method)); MD5_Update(&ctx, ":", 1); MD5_Update(&ctx, uri, strlen(uri)); MD5_Final(digest_mu, &ctx); int i; char buf[33]; for (i=0; i<16; i++) sprintf(buf + 2*i, "%02X", digest_urp[i]); MD5_Init(&ctx); MD5_Update(&ctx, buf, 32); MD5_Update(&ctx, ":", 1); MD5_Update(&ctx, *nonce, strlen(*nonce)); MD5_Update(&ctx, ":", 1); for (i=0; i<16; i++) sprintf(buf + 2*i, "%02X", digest_mu[i]); MD5_Update(&ctx, buf, 32); MD5_Final(digest_total, &ctx); for (i=0; i<16; i++) sprintf(buf + 2*i, "%02X", digest_total[i]); if (!strcmp(response, buf)) return 0; warn("auth failed"); authenticate: resp->respcode = 401; int hdrlen = strlen(*nonce) + 40; char *authhdr = malloc(hdrlen); snprintf(authhdr, hdrlen, "Digest realm=\"taco\", nonce=\"%s\"", *nonce); msg_add_header(resp, "WWW-Authenticate", authhdr); free(authhdr); return 1; }
int cckeychange(reader *r, writer *w, char *keyword_in, char *keyword_out) { /* --decrypt-- */ word32 state_in[8]; word32 seed_in[8]; word8 *statec_in = (word8 *)state_in; word8 *seedchar_in = (word8 *)seed_in; roundkey rkk_in; /* --encrypt-- */ word32 state_out[8]; word8 *statec_out = (word8 *)state_out; roundkey rkk_out; /* --shared-- */ word32 key[8]; int i, c, cc; int st; /* --decrypt-- */ /* generate the roundkey */ hashstring(keyword_in, key); xrijndaelKeySched(key, 256, 256, &rkk_in); /* --encrypt-- */ /* generate the roundkey */ hashstring(keyword_out, key); xrijndaelKeySched(key, 256, 256, &rkk_out); /* --decrypt-- */ /* read the seed */ for (i=0; i<32; i++) { seedchar_in[i] = statec_in[i] = cc = r->bgetc(r); if (cc == EOF) { if (errno) return -1; else return 1; /* error: less than 32 characters in file */ } } /* decrypt the seed with the given keyword */ xrijndaelDecrypt(seed_in, &rkk_in); /* check the "magic number". */ if (strncmp(seedchar_in, MAGIC, 4)) { return 2; /* error: wrong key or algorithm */ } /* key seems to match; generate new header */ /* --encrypt-- */ /* make a nonce */ make_nonce(state_out); /* mark the nonce with a "magic number". */ strncpy(statec_out, MAGIC, 4); /* encrypt the nonce with the given keyword */ xrijndaelEncrypt(state_out, &rkk_out); /* write the seed (header) */ for (i=0; i<32; i++) { st = w->bputc(statec_out[i], w); if (st<0) return -1; } /* --common, interleaved-- */ /* transform the body of the stream */ cc = r->bgetc(r); while (cc != EOF) { xrijndaelEncrypt(state_in, &rkk_in); xrijndaelEncrypt(state_out, &rkk_out); for (i=0; i<32 && cc != EOF; i++) { c = cc ^ statec_in[i]; statec_in[i] = cc; cc = c ^ statec_out[i]; statec_out[i] = cc; st = w->bputc(cc, w); if (st<0) return -1; cc = r->bgetc(r); } } if (errno) return -1; return w->beof(w); }