static int srp_callback(gnutls_session_t session, const char *username, gnutls_datum_t *salt, gnutls_datum_t *verifier, gnutls_datum_t *generator, gnutls_datum_t *prime) { int ret; if ( strcmp(username, "prelude-adduser") != 0 ) return -1; salt->size = 4; salt->data = gnutls_malloc(4); if ( ! salt->data ) { fprintf(stderr, "memory exhausted.\n"); return -1; } gcry_randomize(salt->data, salt->size, GCRY_WEAK_RANDOM); ret = copy_datum(generator, &gnutls_srp_1024_group_generator); if ( ret < 0 ) return -1; ret = copy_datum(prime, &gnutls_srp_1024_group_prime); if ( ret < 0 ) return -1; return gnutls_srp_verifier(username, one_shot_passwd, salt, generator, prime, verifier); }
/* The format of a tpasswd file is: * username:verifier:salt:index * * index is the index of the prime-generator pair in tpasswd.conf */ static int _verify_passwd_int(const char *username, const char *passwd, char *verifier, const char *salt, const gnutls_datum_t * g, const gnutls_datum_t * n) { char _salt[1024]; gnutls_datum_t tmp, raw_salt, new_verifier; size_t salt_size; char *pos; if (salt == NULL || verifier == NULL) return -1; if (strlen(salt) >= sizeof(_salt)) { fprintf(stderr, "Too long salt.\n"); return -1; } /* copy salt, and null terminate after the ':' */ strcpy(_salt, salt); pos = strchr(_salt, ':'); if (pos != NULL) *pos = 0; /* convert salt to binary. */ tmp.data = (void *) _salt; tmp.size = strlen(_salt); if (gnutls_srp_base64_decode_alloc(&tmp, &raw_salt) < 0) { fprintf(stderr, "Could not decode salt.\n"); return -1; } if (gnutls_srp_verifier (username, passwd, &raw_salt, g, n, &new_verifier) < 0) { fprintf(stderr, "Could not make the verifier\n"); return -1; } free(raw_salt.data); /* encode the verifier into _salt */ salt_size = sizeof(_salt); memset(_salt, 0, salt_size); if (gnutls_srp_base64_encode(&new_verifier, _salt, &salt_size) < 0) { fprintf(stderr, "Encoding error\n"); return -1; } free(new_verifier.data); if (strncmp(verifier, _salt, strlen(_salt)) == 0) { fprintf(stderr, "Password verified\n"); return 0; } else { fprintf(stderr, "Password does NOT match\n"); } return -1; }
static char * _srp_crypt (const char *username, const char *passwd, int salt_size, const gnutls_datum_t * g, const gnutls_datum_t * n) { unsigned char salt[128]; static char result[1024]; gnutls_datum_t dat_salt, txt_salt; gnutls_datum_t verifier, txt_verifier; if ((unsigned) salt_size > sizeof (salt)) return NULL; /* generate the salt */ if (gnutls_rnd (GNUTLS_RND_NONCE, salt, salt_size) < 0) { fprintf (stderr, "Could not create nonce\n"); return NULL; } dat_salt.data = salt; dat_salt.size = salt_size; if (gnutls_srp_verifier (username, passwd, &dat_salt, g, n, &verifier) < 0) { fprintf (stderr, "Error getting verifier\n"); return NULL; } /* base64 encode the verifier */ if (gnutls_srp_base64_encode_alloc (&verifier, &txt_verifier) < 0) { fprintf (stderr, "Error encoding\n"); free (verifier.data); return NULL; } free (verifier.data); if (gnutls_srp_base64_encode_alloc (&dat_salt, &txt_salt) < 0) { fprintf (stderr, "Error encoding\n"); return NULL; } sprintf (result, "%s:%s", txt_verifier.data, txt_salt.data); free (txt_salt.data); free (txt_verifier.data); return result; }