mech-rpa.c revision 63969c244e8973a61760a98a23b127827d3d652c
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * Compuserve RPA authentication mechanism.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * This program is free software; you can redistribute it and/or modify
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * it under the terms of the GNU Lesser General Public License as published
4b9355028a364c6e901ce2d8a7d91180d3e55399Timo Sirainen * by the Free Software Foundation; either version 2 of the License, or
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * (at your option) any later version.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* cached: */
17062405030a3fa095e43d5b8b71afc5536f0a22Timo Sirainen unsigned char *pwd_md5;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const unsigned char *service_ucs2be;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const unsigned char *username_ucs2be;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen const unsigned char *realm_ucs2be;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /* requested: */
17062405030a3fa095e43d5b8b71afc5536f0a22Timo Sirainen /* received: */
17062405030a3fa095e43d5b8b71afc5536f0a22Timo Sirainen unsigned char *user_challenge;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned char *user_response;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned char *session_key;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen/* Object id encoded using ASN.1 DER */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstatic const unsigned char rpa_oid[] = {
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x73, 0x01, 0x01
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenvoid *ucs2be_str(pool_t pool, const char *str, size_t *size);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * Compute client -> server authentication response.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstatic void rpa_user_response(struct rpa_auth_request *auth,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned char *digest)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned char z[48];
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen memset(z, 0, sizeof(z));
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->username_ucs2be, auth->username_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_ucs2be, auth->service_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->realm_ucs2be, auth->realm_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->user_challenge, auth->user_challenge_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_challenge, RPA_SCHALLENGE_LEN);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_timestamp, RPA_TIMESTAMP_LEN);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * Compute server -> client authentication response.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenstatic void rpa_server_response(struct rpa_auth_request *auth,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned char *digest)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen unsigned char z[48];
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen memset(z, 0, sizeof(z));
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_ucs2be, auth->service_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->username_ucs2be, auth->username_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->realm_ucs2be, auth->realm_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_challenge, RPA_SCHALLENGE_LEN);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->user_challenge, auth->user_challenge_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_timestamp, RPA_TIMESTAMP_LEN);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen for (i = 0; i < 16; i++)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_ucs2be, auth->service_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->username_ucs2be, auth->username_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->realm_ucs2be, auth->realm_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_challenge, RPA_SCHALLENGE_LEN);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->user_challenge, auth->user_challenge_len);
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen md5_update(&ctx, auth->service_timestamp, RPA_TIMESTAMP_LEN);
const char **error)
const unsigned char *p = data;
unsigned int len = 0;
return NULL;
if (*p++ != ASN1_APPLICATION) {
return NULL;
while (nbytes-- > 0) {
if (p >= end) {
return NULL;
len = *p++;
return NULL;
return NULL;
return NULL;
return p + sizeof(rpa_oid);
if (p == NULL)
return FALSE;
return FALSE;
return FALSE;
return FALSE;
if (p != end) {
return FALSE;
return TRUE;
const unsigned char *p = *data;
unsigned int len;
if (p > end)
len = *p++;
return len;
unsigned int len;
const char *user;
if (p == NULL)
return FALSE;
return FALSE;
return FALSE;
p += len;
return FALSE;
return FALSE;
if (p != end) {
return FALSE;
return TRUE;
unsigned int realms_len;
unsigned int length;
const unsigned char *token2;
if (verbose) {
return TRUE;
return TRUE;
const unsigned char *token4;
const char *error;
if (verbose) {
return TRUE;
if (verbose) {
return TRUE;
return TRUE;
return TRUE;
return TRUE;
if (verbose) {
return TRUE;
return TRUE;
return TRUE;