Add SRP.
This commit is contained in:
parent
13e230d505
commit
a149b2466e
3
CHANGES
3
CHANGES
@ -4,6 +4,9 @@
|
||||
|
||||
Changes between 1.0.0d and 1.0.1 [xx XXX xxxx]
|
||||
|
||||
*) Add SRP support.
|
||||
[Tom Wu <tjw@cs.stanford.edu> and Ben Laurie]
|
||||
|
||||
*) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id.
|
||||
[Steve Henson]
|
||||
|
||||
|
@ -946,6 +946,12 @@ if (defined($disabled{"ec"}) || defined($disabled{"dsa"})
|
||||
$disabled{"gost"} = "forced";
|
||||
}
|
||||
|
||||
# SRP requires TLSEXT
|
||||
if (defined($disabled{"tlsext"}))
|
||||
{
|
||||
$disabled{"srp"} = "forced";
|
||||
}
|
||||
|
||||
if ($target eq "TABLE") {
|
||||
foreach $target (sort keys %table) {
|
||||
print_table_entry($target);
|
||||
|
@ -121,7 +121,7 @@ SDIRS= \
|
||||
bn ec rsa dsa ecdsa dh ecdh dso engine \
|
||||
buffer bio stack lhash rand err \
|
||||
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
|
||||
cms pqueue ts jpake store
|
||||
cms pqueue ts jpake srp store
|
||||
# keep in mind that the above list is adjusted by ./Configure
|
||||
# according to no-xxx arguments...
|
||||
|
||||
|
@ -39,7 +39,7 @@ E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
|
||||
ca crl rsa rsautl dsa dsaparam ec ecparam \
|
||||
x509 genrsa gendsa genpkey s_server s_client speed \
|
||||
s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
|
||||
pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts
|
||||
pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp
|
||||
|
||||
PROGS= $(PROGRAM).c
|
||||
|
||||
@ -56,7 +56,7 @@ E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o er
|
||||
x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
|
||||
s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
|
||||
ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \
|
||||
spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o
|
||||
spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o
|
||||
|
||||
E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
|
||||
pkcs7.c crl2p7.c crl.c \
|
||||
@ -64,7 +64,7 @@ E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.
|
||||
x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \
|
||||
s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
|
||||
ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \
|
||||
spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c
|
||||
spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c srp.c
|
||||
|
||||
SRC=$(E_SRC)
|
||||
|
||||
|
6
apps/demoSRP/srp_verifier.txt
Normal file
6
apps/demoSRP/srp_verifier.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# This is a file that will be filled by the openssl srp routine.
|
||||
# You can initialize the file with additional groups, these are
|
||||
# records starting with a I followed by the g and N values and the id.
|
||||
# The exact values ... you have to dig this out from the source of srp.c
|
||||
# or srp_vfy.c
|
||||
# The last value of an I is used as the default group for new users.
|
1
apps/demoSRP/srp_verifier.txt.attr
Normal file
1
apps/demoSRP/srp_verifier.txt.attr
Normal file
@ -0,0 +1 @@
|
||||
unique_subject = yes
|
@ -44,6 +44,7 @@ extern int smime_main(int argc,char *argv[]);
|
||||
extern int rand_main(int argc,char *argv[]);
|
||||
extern int engine_main(int argc,char *argv[]);
|
||||
extern int ocsp_main(int argc,char *argv[]);
|
||||
extern int srp_main(int argc,char *argv[]);
|
||||
extern int prime_main(int argc,char *argv[]);
|
||||
extern int ts_main(int argc,char *argv[]);
|
||||
|
||||
@ -144,6 +145,9 @@ FUNCTION functions[] = {
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
{FUNC_TYPE_GENERAL,"srp",srp_main},
|
||||
#endif
|
||||
{FUNC_TYPE_GENERAL,"prime",prime_main},
|
||||
{FUNC_TYPE_GENERAL,"ts",ts_main},
|
||||
|
180
apps/s_client.c
180
apps/s_client.c
@ -163,6 +163,9 @@ typedef unsigned int u_int;
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#include <openssl/bn.h>
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include <openssl/srp.h>
|
||||
#endif
|
||||
#include "s_apps.h"
|
||||
#include "timeouts.h"
|
||||
|
||||
@ -315,6 +318,13 @@ static void sc_usage(void)
|
||||
# ifndef OPENSSL_NO_JPAKE
|
||||
BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n");
|
||||
# endif
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
BIO_printf(bio_err," -srpuser user - SRP authentification for 'user'\n");
|
||||
BIO_printf(bio_err," -srppass arg - password for 'user'\n");
|
||||
BIO_printf(bio_err," -srp_lateuser - SRP username into second ClientHello message\n");
|
||||
BIO_printf(bio_err," -srp_moregroups - Tolerate other than the known g N values.\n");
|
||||
BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N);
|
||||
#endif
|
||||
BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
|
||||
BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
|
||||
@ -367,6 +377,112 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|
||||
/* This is a context that we pass to all callbacks */
|
||||
typedef struct srp_arg_st
|
||||
{
|
||||
char *srppassin;
|
||||
char *srplogin;
|
||||
int msg; /* copy from c_msg */
|
||||
int debug; /* copy from c_debug */
|
||||
int amp; /* allow more groups */
|
||||
int strength /* minimal size for N */ ;
|
||||
} SRP_ARG;
|
||||
|
||||
#define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
|
||||
|
||||
static int SRP_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
|
||||
{
|
||||
BN_CTX *bn_ctx = BN_CTX_new();
|
||||
BIGNUM *p = BN_new();
|
||||
BIGNUM *r = BN_new();
|
||||
int ret =
|
||||
g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
|
||||
BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
|
||||
p != NULL && BN_rshift1(p, N) &&
|
||||
|
||||
/* p = (N-1)/2 */
|
||||
BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
|
||||
r != NULL &&
|
||||
|
||||
/* verify g^((N-1)/2) == -1 (mod N) */
|
||||
BN_mod_exp(r, g, p, N, bn_ctx) &&
|
||||
BN_add_word(r, 1) &&
|
||||
BN_cmp(r, N) == 0;
|
||||
|
||||
if(r)
|
||||
BN_free(r);
|
||||
if(p)
|
||||
BN_free(p);
|
||||
if(bn_ctx)
|
||||
BN_CTX_free(bn_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
|
||||
{
|
||||
SRP_ARG *srp_arg = (SRP_ARG *)arg;
|
||||
BIGNUM *N = NULL, *g = NULL;
|
||||
if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
|
||||
return 0;
|
||||
if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1)
|
||||
{
|
||||
BIO_printf(bio_err, "SRP parameters:\n");
|
||||
BIO_printf(bio_err,"\tN="); BN_print(bio_err,N);
|
||||
BIO_printf(bio_err,"\n\tg="); BN_print(bio_err,g);
|
||||
BIO_printf(bio_err,"\n");
|
||||
}
|
||||
|
||||
if (SRP_check_known_gN_param(g,N))
|
||||
return 1;
|
||||
|
||||
if (srp_arg->amp == 1)
|
||||
{
|
||||
if (srp_arg->debug)
|
||||
BIO_printf(bio_err, "SRP param N and g are not known params, going to check deeper.\n");
|
||||
|
||||
/* The srp_moregroups must be used with caution, testing primes costs time.
|
||||
Implementors should rather add the value to the known ones.
|
||||
The minimal size has already been tested.
|
||||
*/
|
||||
if (BN_num_bits(g) <= BN_BITS && SRP_Verify_N_and_g(N,g))
|
||||
return 1;
|
||||
}
|
||||
BIO_printf(bio_err, "SRP param N and g rejected.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PWD_STRLEN 1024
|
||||
|
||||
static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
|
||||
{
|
||||
SRP_ARG *srp_arg = (SRP_ARG *)arg;
|
||||
char *pass = (char *)OPENSSL_malloc(PWD_STRLEN+1);
|
||||
PW_CB_DATA cb_tmp;
|
||||
int l;
|
||||
|
||||
cb_tmp.password = (char *)srp_arg->srppassin;
|
||||
cb_tmp.prompt_info = "SRP user";
|
||||
if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp))<0)
|
||||
{
|
||||
BIO_printf (bio_err, "Can't read Password\n");
|
||||
OPENSSL_free(pass);
|
||||
return NULL;
|
||||
}
|
||||
*(pass+l)= '\0';
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
|
||||
{
|
||||
SRP_ARG *srp_arg = (SRP_ARG *)arg;
|
||||
return BUF_strdup(srp_arg->srplogin);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum
|
||||
@ -440,6 +556,11 @@ int MAIN(int argc, char **argv)
|
||||
#ifndef OPENSSL_NO_JPAKE
|
||||
char *jpake_secret = NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
char * srppass = NULL;
|
||||
int srp_lateuser = 0;
|
||||
SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
meth=SSLv23_client_method();
|
||||
@ -589,6 +710,37 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (strcmp(*argv,"-srpuser") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_arg.srplogin= *(++argv);
|
||||
meth=TLSv1_client_method();
|
||||
}
|
||||
else if (strcmp(*argv,"-srppass") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srppass= *(++argv);
|
||||
meth=TLSv1_client_method();
|
||||
}
|
||||
else if (strcmp(*argv,"-srp_strength") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_arg.strength=atoi(*(++argv));
|
||||
BIO_printf(bio_err,"SRP minimal length for N is %d\n",srp_arg.strength);
|
||||
meth=TLSv1_client_method();
|
||||
}
|
||||
else if (strcmp(*argv,"-srp_lateuser") == 0)
|
||||
{
|
||||
srp_lateuser= 1;
|
||||
meth=TLSv1_client_method();
|
||||
}
|
||||
else if (strcmp(*argv,"-srp_moregroups") == 0)
|
||||
{
|
||||
srp_arg.amp=1;
|
||||
meth=TLSv1_client_method();
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
else if (strcmp(*argv,"-ssl2") == 0)
|
||||
meth=SSLv2_client_method();
|
||||
@ -840,6 +992,14 @@ bad:
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
|
||||
{
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx=SSL_CTX_new(meth);
|
||||
if (ctx == NULL)
|
||||
{
|
||||
@ -919,6 +1079,26 @@ bad:
|
||||
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
|
||||
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (srp_arg.srplogin)
|
||||
{
|
||||
if (srp_lateuser)
|
||||
SSL_CTX_set_srp_missing_srp_username_callback(ctx,missing_srp_username_callback);
|
||||
else if (!SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
|
||||
{
|
||||
BIO_printf(bio_err,"Unable to set SRP username\n");
|
||||
goto end;
|
||||
}
|
||||
srp_arg.msg = c_msg;
|
||||
srp_arg.debug = c_debug ;
|
||||
SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
|
||||
SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
|
||||
SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
|
||||
if (c_msg || c_debug || srp_arg.amp == 0)
|
||||
SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
con=SSL_new(ctx);
|
||||
|
@ -186,6 +186,9 @@ typedef unsigned int u_int;
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include <openssl/srp.h>
|
||||
#endif
|
||||
#include "s_apps.h"
|
||||
#include "timeouts.h"
|
||||
|
||||
@ -369,6 +372,40 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* This is a context that we pass to callbacks */
|
||||
typedef struct srpsrvparm_st
|
||||
{
|
||||
int verbose;
|
||||
char *login;
|
||||
SRP_VBASE *vb;
|
||||
} srpsrvparm;
|
||||
|
||||
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
|
||||
{
|
||||
srpsrvparm *p = (srpsrvparm *) arg;
|
||||
SRP_user_pwd *user;
|
||||
|
||||
p->login = BUF_strdup(SSL_get_srp_username(s));
|
||||
BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
|
||||
|
||||
user = SRP_VBASE_get_by_user(p->vb, p->login);
|
||||
if (user == NULL)
|
||||
{
|
||||
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
|
||||
return SSL3_AL_FATAL;
|
||||
}
|
||||
if (SSL_set_srp_server_param(s, user->N, user->g, user->s, user->v,
|
||||
user->info) < 0)
|
||||
{
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL3_AL_FATAL;
|
||||
}
|
||||
return SSL_ERROR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MONOLITH
|
||||
static void s_server_init(void)
|
||||
{
|
||||
@ -455,6 +492,10 @@ static void sv_usage(void)
|
||||
# ifndef OPENSSL_NO_JPAKE
|
||||
BIO_printf(bio_err," -jpake arg - JPAKE secret to use\n");
|
||||
# endif
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
BIO_printf(bio_err," -srpvfile file - The verifier file for SRP\n");
|
||||
BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n");
|
||||
#endif
|
||||
BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
|
||||
BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
|
||||
@ -874,12 +915,21 @@ int MAIN(int argc, char *argv[])
|
||||
/* by default do not send a PSK identity hint */
|
||||
static char *psk_identity_hint=NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
char *srpuserseed = NULL;
|
||||
char *srp_verifier_file = NULL;
|
||||
srpsrvparm p;
|
||||
#endif
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
meth=SSLv23_server_method();
|
||||
#elif !defined(OPENSSL_NO_SSL3)
|
||||
meth=SSLv3_server_method();
|
||||
#elif !defined(OPENSSL_NO_SSL2)
|
||||
meth=SSLv2_server_method();
|
||||
#elif !defined(OPENSSL_NO_TLS1)
|
||||
meth=TLSv1_server_method();
|
||||
#else
|
||||
/* #error no SSL version enabled */
|
||||
#endif
|
||||
|
||||
local_argc=argc;
|
||||
@ -1111,6 +1161,20 @@ int MAIN(int argc, char *argv[])
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (strcmp(*argv, "-srpvfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_verifier_file = *(++argv);
|
||||
meth=TLSv1_server_method();
|
||||
}
|
||||
else if (strcmp(*argv, "-srpuserseed") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srpuserseed = *(++argv);
|
||||
meth=TLSv1_server_method();
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv,"-www") == 0)
|
||||
{ www=1; }
|
||||
@ -1690,6 +1754,23 @@ bad:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (srp_verifier_file != NULL)
|
||||
{
|
||||
p.vb = SRP_VBASE_new(srpuserseed);
|
||||
if ((ret = SRP_VBASE_init(p.vb, srp_verifier_file)) != SRP_NO_ERROR)
|
||||
{
|
||||
BIO_printf(bio_err,
|
||||
"Cannot initialize SRP verifier file \"%s\":ret=%d\n",
|
||||
srp_verifier_file, ret);
|
||||
goto end;
|
||||
}
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
|
||||
SSL_CTX_set_srp_cb_arg(ctx, &p);
|
||||
SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (CAfile != NULL)
|
||||
{
|
||||
SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
|
||||
|
759
apps/srp.c
Normal file
759
apps/srp.c
Normal file
@ -0,0 +1,759 @@
|
||||
/* apps/srp.c */
|
||||
/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/txt_db.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/srp.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#undef PROG
|
||||
#define PROG srp_main
|
||||
|
||||
#define BASE_SECTION "srp"
|
||||
#define CONFIG_FILE "openssl.cnf"
|
||||
|
||||
#define ENV_RANDFILE "RANDFILE"
|
||||
|
||||
#define ENV_DATABASE "srpvfile"
|
||||
#define ENV_DEFAULT_SRP "default_srp"
|
||||
|
||||
static char *srp_usage[]={
|
||||
"usage: srp [args] [user] \n",
|
||||
"\n",
|
||||
" -verbose Talk alot while doing things\n",
|
||||
" -config file A config file\n",
|
||||
" -name arg The particular srp definition to use\n",
|
||||
" -srpvfile arg The srp verifier file name\n",
|
||||
" -add add an user and srp verifier\n",
|
||||
" -modify modify the srp verifier of an existing user\n",
|
||||
" -delete delete user from verifier file\n",
|
||||
" -list list user\n",
|
||||
" -gn arg g and N values to be used for new verifier\n",
|
||||
" -userinfo arg additional info to be set for user\n",
|
||||
" -passin arg input file pass phrase source\n",
|
||||
" -passout arg output file pass phrase source\n",
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
" -engine e - use engine e, possibly a hardware device.\n",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef EFENCE
|
||||
extern int EF_PROTECT_FREE;
|
||||
extern int EF_PROTECT_BELOW;
|
||||
extern int EF_ALIGNMENT;
|
||||
#endif
|
||||
|
||||
static CONF *conf=NULL;
|
||||
static char *section=NULL;
|
||||
|
||||
#define VERBOSE if (verbose)
|
||||
#define VVERBOSE if (verbose>1)
|
||||
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
||||
static int get_index(CA_DB *db, char* id, char type)
|
||||
{
|
||||
char ** pp;
|
||||
int i;
|
||||
if (id == NULL) return -1;
|
||||
if (type == DB_SRP_INDEX)
|
||||
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
|
||||
{
|
||||
pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
|
||||
if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id, pp[DB_srpid]))
|
||||
return i;
|
||||
}
|
||||
else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
|
||||
{
|
||||
pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
|
||||
|
||||
if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid]))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s)
|
||||
{
|
||||
if (indx >= 0 && verbose)
|
||||
{
|
||||
int j;
|
||||
char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, indx);
|
||||
BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]);
|
||||
for (j = 0; j < DB_NUMBER; j++)
|
||||
{
|
||||
BIO_printf(bio_err," %d = \"%s\"\n", j, pp[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose)
|
||||
{
|
||||
print_entry(db, bio, indexindex, verbose, "g N entry") ;
|
||||
}
|
||||
|
||||
static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose)
|
||||
{
|
||||
if (verbose > 0)
|
||||
{
|
||||
char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
|
||||
|
||||
if (pp[DB_srptype][0] != 'I')
|
||||
{
|
||||
print_entry(db, bio, userindex, verbose, "User entry");
|
||||
print_entry(db, bio, get_index(db, pp[DB_srpgN], 'I'), verbose, "g N entry");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int update_index(CA_DB *db, BIO *bio, char **row)
|
||||
{
|
||||
char ** irow;
|
||||
int i;
|
||||
|
||||
if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"Memory allocation failure\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0; i<DB_NUMBER; i++)
|
||||
{
|
||||
irow[i]=row[i];
|
||||
row[i]=NULL;
|
||||
}
|
||||
irow[DB_NUMBER]=NULL;
|
||||
|
||||
if (!TXT_DB_insert(db->db,irow))
|
||||
{
|
||||
BIO_printf(bio,"failed to update srpvfile\n");
|
||||
BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error);
|
||||
OPENSSL_free(irow);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void lookup_fail(const char *name, char *tag)
|
||||
{
|
||||
BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
|
||||
}
|
||||
|
||||
|
||||
static char *srp_verify_user(const char *user, const char *srp_verifier,
|
||||
char *srp_usersalt, const char *g, const char *N,
|
||||
const char *passin, BIO *bio, int verbose)
|
||||
{
|
||||
char password[1024];
|
||||
PW_CB_DATA cb_tmp;
|
||||
char *verifier = NULL;
|
||||
char *gNid = NULL;
|
||||
|
||||
cb_tmp.prompt_info = user;
|
||||
cb_tmp.password = passin;
|
||||
|
||||
if (password_callback(password, 1024, 0, &cb_tmp) >0)
|
||||
{
|
||||
VERBOSE BIO_printf(bio,"Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,srp_verifier,srp_usersalt, g, N);
|
||||
BIO_printf(bio, "Pass %s\n", password);
|
||||
|
||||
if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, g)))
|
||||
{
|
||||
BIO_printf(bio, "Internal error validating SRP verifier\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(verifier, srp_verifier))
|
||||
gNid = NULL;
|
||||
OPENSSL_free(verifier);
|
||||
}
|
||||
}
|
||||
return gNid;
|
||||
}
|
||||
|
||||
static char *srp_create_user(char *user, char **srp_verifier,
|
||||
char **srp_usersalt, char *g, char *N,
|
||||
char *passout, BIO *bio, int verbose)
|
||||
{
|
||||
char password[1024];
|
||||
PW_CB_DATA cb_tmp;
|
||||
char *gNid = NULL;
|
||||
char *salt = NULL;
|
||||
cb_tmp.prompt_info = user;
|
||||
cb_tmp.password = passout;
|
||||
|
||||
if (password_callback(password,1024,1,&cb_tmp) >0)
|
||||
{
|
||||
VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N);
|
||||
if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g)))
|
||||
{
|
||||
BIO_printf(bio,"Internal error creating SRP verifier\n");
|
||||
}
|
||||
else
|
||||
*srp_usersalt = salt;
|
||||
VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier);
|
||||
|
||||
}
|
||||
return gNid;
|
||||
}
|
||||
|
||||
int MAIN(int argc, char **argv)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE *e = NULL;
|
||||
#endif
|
||||
int add_user = 0;
|
||||
int list_user= 0;
|
||||
int delete_user= 0;
|
||||
int modify_user= 0;
|
||||
char * user = NULL;
|
||||
|
||||
char *passargin = NULL, *passargout = NULL;
|
||||
char *passin = NULL, *passout = NULL;
|
||||
char * gN = NULL;
|
||||
int gNindex = -1;
|
||||
char ** gNrow = NULL;
|
||||
int maxgN = -1;
|
||||
|
||||
char * userinfo = NULL;
|
||||
|
||||
int badops=0;
|
||||
int ret=1;
|
||||
int errors=0;
|
||||
int verbose=0;
|
||||
int doupdatedb=0;
|
||||
char *configfile=NULL;
|
||||
char *dbfile=NULL;
|
||||
CA_DB *db=NULL;
|
||||
char **pp ;
|
||||
int i;
|
||||
long errorline = -1;
|
||||
char *randfile=NULL;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *engine = NULL;
|
||||
#endif
|
||||
char *tofree=NULL;
|
||||
DB_ATTR db_attr;
|
||||
|
||||
#ifdef EFENCE
|
||||
EF_PROTECT_FREE=1;
|
||||
EF_PROTECT_BELOW=1;
|
||||
EF_ALIGNMENT=0;
|
||||
#endif
|
||||
|
||||
apps_startup();
|
||||
|
||||
conf = NULL;
|
||||
section = NULL;
|
||||
|
||||
if (bio_err == NULL)
|
||||
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
|
||||
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
while (argc >= 1 && badops == 0)
|
||||
{
|
||||
if (strcmp(*argv,"-verbose") == 0)
|
||||
verbose++;
|
||||
else if (strcmp(*argv,"-config") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
configfile= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-name") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
section= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-srpvfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
dbfile= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-add") == 0)
|
||||
add_user=1;
|
||||
else if (strcmp(*argv,"-delete") == 0)
|
||||
delete_user=1;
|
||||
else if (strcmp(*argv,"-modify") == 0)
|
||||
modify_user=1;
|
||||
else if (strcmp(*argv,"-list") == 0)
|
||||
list_user=1;
|
||||
else if (strcmp(*argv,"-gn") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
gN= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-userinfo") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
userinfo= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-passin") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
passargin= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-passout") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
passargout= *(++argv);
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
else if (strcmp(*argv,"-engine") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
engine= *(++argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (**argv == '-')
|
||||
{
|
||||
bad:
|
||||
BIO_printf(bio_err,"unknown option %s\n",*argv);
|
||||
badops=1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (dbfile && configfile)
|
||||
{
|
||||
BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n");
|
||||
badops = 1;
|
||||
}
|
||||
if (add_user+delete_user+modify_user+list_user != 1)
|
||||
{
|
||||
BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n");
|
||||
badops = 1;
|
||||
}
|
||||
if (delete_user+modify_user+delete_user== 1 && argc <= 0)
|
||||
{
|
||||
BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n");
|
||||
badops = 1;
|
||||
}
|
||||
if ((passin || passout) && argc != 1 )
|
||||
{
|
||||
BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n");
|
||||
badops = 1;
|
||||
}
|
||||
|
||||
if (badops)
|
||||
{
|
||||
for (pp=srp_usage; (*pp != NULL); pp++)
|
||||
BIO_printf(bio_err,"%s",*pp);
|
||||
|
||||
BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
|
||||
BIO_printf(bio_err," load the file (or the files in the directory) into\n");
|
||||
BIO_printf(bio_err," the random number generator\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
e = setup_engine(bio_err, engine, 0);
|
||||
#endif
|
||||
|
||||
if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
|
||||
{
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!dbfile)
|
||||
{
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
tofree=NULL;
|
||||
if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
|
||||
if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
|
||||
if (configfile == NULL)
|
||||
{
|
||||
const char *s=X509_get_default_cert_area();
|
||||
size_t len;
|
||||
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
len = strlen(s)+sizeof(CONFIG_FILE);
|
||||
tofree=OPENSSL_malloc(len);
|
||||
strcpy(tofree,s);
|
||||
#else
|
||||
len = strlen(s)+sizeof(CONFIG_FILE)+1;
|
||||
tofree=OPENSSL_malloc(len);
|
||||
BUF_strlcpy(tofree,s,len);
|
||||
BUF_strlcat(tofree,"/",len);
|
||||
#endif
|
||||
BUF_strlcat(tofree,CONFIG_FILE,len);
|
||||
configfile=tofree;
|
||||
}
|
||||
|
||||
VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile);
|
||||
conf = NCONF_new(NULL);
|
||||
if (NCONF_load(conf,configfile,&errorline) <= 0)
|
||||
{
|
||||
if (errorline <= 0)
|
||||
BIO_printf(bio_err,"error loading the config file '%s'\n",
|
||||
configfile);
|
||||
else
|
||||
BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
|
||||
,errorline,configfile);
|
||||
goto err;
|
||||
}
|
||||
if(tofree)
|
||||
{
|
||||
OPENSSL_free(tofree);
|
||||
tofree = NULL;
|
||||
}
|
||||
|
||||
if (!load_config(bio_err, conf))
|
||||
goto err;
|
||||
|
||||
/* Lets get the config section we are using */
|
||||
if (section == NULL)
|
||||
{
|
||||
VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n");
|
||||
|
||||
section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP);
|
||||
if (section == NULL)
|
||||
{
|
||||
lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (randfile == NULL && conf)
|
||||
randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
|
||||
|
||||
|
||||
VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section);
|
||||
|
||||
if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
|
||||
{
|
||||
lookup_fail(section,ENV_DATABASE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
}
|
||||
if (randfile == NULL)
|
||||
ERR_clear_error();
|
||||
else
|
||||
app_RAND_load_file(randfile, bio_err, 0);
|
||||
|
||||
VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile);
|
||||
|
||||
db = load_index(dbfile, &db_attr);
|
||||
if (db == NULL) goto err;
|
||||
|
||||
/* Lets check some fields */
|
||||
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
|
||||
{
|
||||
pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
|
||||
|
||||
if (pp[DB_srptype][0] == DB_SRP_INDEX)
|
||||
{
|
||||
maxgN = i;
|
||||
if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
|
||||
gNindex = i;
|
||||
|
||||
print_index(db, bio_err, i, verbose > 1);
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE BIO_printf(bio_err, "Database initialised\n");
|
||||
|
||||
if (gNindex >= 0)
|
||||
{
|
||||
gNrow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, gNindex);
|
||||
print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N") ;
|
||||
}
|
||||
else if (maxgN > 0 && !SRP_get_default_gN(gN))
|
||||
{
|
||||
BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
VERBOSE BIO_printf(bio_err, "Database has no g N information.\n");
|
||||
gNrow = NULL;
|
||||
}
|
||||
|
||||
|
||||
VVERBOSE BIO_printf(bio_err,"Starting user processing\n");
|
||||
|
||||
if (argc > 0)
|
||||
user = *(argv++) ;
|
||||
|
||||
while (list_user || user)
|
||||
{
|
||||
int userindex = -1;
|
||||
if (user)
|
||||
VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user);
|
||||
if ((userindex = get_index(db, user, 'U')) >= 0)
|
||||
{
|
||||
print_user(db, bio_err, userindex, (verbose > 0) || list_user);
|
||||
}
|
||||
|
||||
if (list_user)
|
||||
{
|
||||
if (user == NULL)
|
||||
{
|
||||
BIO_printf(bio_err,"List all users\n");
|
||||
|
||||
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
|
||||
{
|
||||
print_user(db,bio_err, i, 1);
|
||||
}
|
||||
list_user = 0;
|
||||
}
|
||||
else if (userindex < 0)
|
||||
{
|
||||
BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n",
|
||||
user);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
else if (add_user)
|
||||
{
|
||||
if (userindex >= 0)
|
||||
{
|
||||
/* reactivation of a new user */
|
||||
char **row = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
|
||||
BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
|
||||
row[DB_srptype][0] = 'V';
|
||||
|
||||
doupdatedb = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *row[DB_NUMBER] ; char *gNid;
|
||||
row[DB_srpverifier] = NULL;
|
||||
row[DB_srpsalt] = NULL;
|
||||
row[DB_srpinfo] = NULL;
|
||||
if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
|
||||
{
|
||||
BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user);
|
||||
errors++;
|
||||
goto err;
|
||||
}
|
||||
row[DB_srpid] = BUF_strdup(user);
|
||||
row[DB_srptype] = BUF_strdup("v");
|
||||
row[DB_srpgN] = BUF_strdup(gNid);
|
||||
|
||||
if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
|
||||
(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) ||
|
||||
!update_index(db, bio_err, row))
|
||||
{
|
||||
if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]);
|
||||
if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]);
|
||||
if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]);
|
||||
if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]);
|
||||
if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]);
|
||||
if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]);
|
||||
goto err;
|
||||
}
|
||||
doupdatedb = 1;
|
||||
}
|
||||
}
|
||||
else if (modify_user)
|
||||
{
|
||||
if (userindex < 0)
|
||||
{
|
||||
BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user);
|
||||
errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
char **row = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
|
||||
char type = row[DB_srptype][0];
|
||||
if (type == 'v')
|
||||
{
|
||||
BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user);
|
||||
errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *gNid;
|
||||
|
||||
if (row[DB_srptype][0] == 'V')
|
||||
{
|
||||
int user_gN;
|
||||
char **irow = NULL;
|
||||
VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user);
|
||||
if ( (user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
|
||||
irow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
|
||||
|
||||
if (!srp_verify_user(user, row[DB_srpverifier], row[DB_srpsalt], irow ? irow[DB_srpsalt] : row[DB_srpgN], irow ? irow[DB_srpverifier] : NULL, passin, bio_err, verbose))
|
||||
{
|
||||
BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user);
|
||||
errors++;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user);
|
||||
|
||||
if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
|
||||
{
|
||||
BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user);
|
||||
errors++;
|
||||
goto err;
|
||||
}
|
||||
|
||||
row[DB_srptype][0] = 'v';
|
||||
row[DB_srpgN] = BUF_strdup(gNid);
|
||||
|
||||
if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
|
||||
(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))
|
||||
goto err;
|
||||
|
||||
doupdatedb = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (delete_user)
|
||||
{
|
||||
if (userindex < 0)
|
||||
{
|
||||
BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user);
|
||||
errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char **xpp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
|
||||
BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
|
||||
|
||||
xpp[DB_srptype][0] = 'R';
|
||||
|
||||
doupdatedb = 1;
|
||||
}
|
||||
}
|
||||
if (--argc > 0)
|
||||
user = *(argv++) ;
|
||||
else
|
||||
{
|
||||
user = NULL;
|
||||
list_user = 0;
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE BIO_printf(bio_err,"User procession done.\n");
|
||||
|
||||
|
||||
if (doupdatedb)
|
||||
{
|
||||
/* Lets check some fields */
|
||||
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
|
||||
{
|
||||
pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
|
||||
|
||||
if (pp[DB_srptype][0] == 'v')
|
||||
{
|
||||
pp[DB_srptype][0] = 'V';
|
||||
print_user(db, bio_err, i, verbose);
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n");
|
||||
if (!save_index(dbfile, "new", db)) goto err;
|
||||
|
||||
VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n");
|
||||
if (!rotate_index(dbfile, "new", "old")) goto err;
|
||||
|
||||
VERBOSE BIO_printf(bio_err, "srpvfile updated.\n");
|
||||
}
|
||||
|
||||
ret = (errors != 0);
|
||||
err:
|
||||
if (errors != 0)
|
||||
VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors);
|
||||
|
||||
VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret);
|
||||
if(tofree)
|
||||
OPENSSL_free(tofree);
|
||||
if (ret) ERR_print_errors(bio_err);
|
||||
if (randfile) app_RAND_write_file(randfile, bio_err);
|
||||
if (conf) NCONF_free(conf);
|
||||
if (db) free_index(db);
|
||||
|
||||
OBJ_cleanup();
|
||||
apps_shutdown();
|
||||
OPENSSL_EXIT(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
1
crypto/srp/.cvsignore
Normal file
1
crypto/srp/.cvsignore
Normal file
@ -0,0 +1 @@
|
||||
lib
|
91
crypto/srp/Makefile
Normal file
91
crypto/srp/Makefile
Normal file
@ -0,0 +1,91 @@
|
||||
DIR= srp
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES= -I.. -I$(TOP) -I../../include
|
||||
CFLAG=-g
|
||||
INSTALL_PREFIX=
|
||||
OPENSSLDIR= /usr/local/ssl
|
||||
INSTALLTOP=/usr/local/ssl
|
||||
MAKE= make -f Makefile.ssl
|
||||
MAKEDEPPROG= makedepend
|
||||
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
|
||||
MAKEFILE= Makefile.ssl
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=srptest.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC=srp_lib.c srp_vfy.c
|
||||
LIBOBJ=srp_lib.o srp_vfy.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER= srp.h
|
||||
HEADER= $(EXHEADER)
|
||||
|
||||
top:
|
||||
(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
$(AR) $(LIB) $(LIBOBJ)
|
||||
$(RANLIB) $(LIB) || echo Never mind.
|
||||
@touch lib
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
|
||||
|
||||
install:
|
||||
@for i in $(EXHEADER) ; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done;
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
srptest: top srptest.c $(LIB)
|
||||
$(CC) $(CFLAGS) -Wall -Werror -g -o srptest srptest.c $(LIB)
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
depend:
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
srp_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
srp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
srp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
srp_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
srp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
|
||||
srp_lib.o: ../../include/openssl/sha.h ../../include/openssl/srp.h
|
||||
srp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
srp_lib.o: ../cryptlib.h srp_grps.h srp_lcl.h srp_lib.c
|
||||
srp_vfy.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
srp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
srp_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
srp_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
srp_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
srp_vfy.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||
srp_vfy.o: ../../include/openssl/sha.h ../../include/openssl/srp.h
|
||||
srp_vfy.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
srp_vfy.o: ../../include/openssl/txt_db.h ../cryptlib.h srp_lcl.h srp_vfy.c
|
172
crypto/srp/srp.h
Normal file
172
crypto/srp/srp.h
Normal file
@ -0,0 +1,172 @@
|
||||
/* crypto/srp/srp.h */
|
||||
/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
|
||||
* the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#ifndef __SRP_H__
|
||||
#define __SRP_H__
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <openssl/safestack.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
typedef struct SRP_gN_cache_st
|
||||
{
|
||||
char *b64_bn;
|
||||
BIGNUM *bn;
|
||||
} SRP_gN_cache;
|
||||
|
||||
|
||||
DECLARE_STACK_OF(SRP_gN_cache)
|
||||
|
||||
typedef struct SRP_user_pwd_st
|
||||
{
|
||||
char *id;
|
||||
BIGNUM *s;
|
||||
BIGNUM *v;
|
||||
const BIGNUM *g;
|
||||
const BIGNUM *N;
|
||||
char *info;
|
||||
} SRP_user_pwd;
|
||||
|
||||
DECLARE_STACK_OF(SRP_user_pwd)
|
||||
|
||||
typedef struct SRP_VBASE_st
|
||||
{
|
||||
STACK_OF(SRP_user_pwd) *users_pwd;
|
||||
STACK_OF(SRP_gN_cache) *gN_cache;
|
||||
/* to simulate a user */
|
||||
char *seed_key;
|
||||
BIGNUM *default_g;
|
||||
BIGNUM *default_N;
|
||||
} SRP_VBASE;
|
||||
|
||||
|
||||
/*Structure interne pour retenir les couples N et g*/
|
||||
typedef struct SRP_gN_st
|
||||
{
|
||||
char *id;
|
||||
BIGNUM *g;
|
||||
BIGNUM *N;
|
||||
} SRP_gN;
|
||||
|
||||
DECLARE_STACK_OF(SRP_gN)
|
||||
|
||||
SRP_VBASE *SRP_VBASE_new(char *seed_key);
|
||||
int SRP_VBASE_free(SRP_VBASE *vb);
|
||||
int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file);
|
||||
SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
|
||||
char *SRP_create_verifier(const char *user, const char *pass, char **salt,
|
||||
char **verifier, const char *N, const char *g);
|
||||
int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
|
||||
|
||||
|
||||
#define SRP_NO_ERROR 0
|
||||
#define SRP_ERR_VBASE_INCOMPLETE_FILE 1
|
||||
#define SRP_ERR_VBASE_BN_LIB 2
|
||||
#define SRP_ERR_OPEN_FILE 3
|
||||
#define SRP_ERR_MEMORY 4
|
||||
|
||||
#define DB_srptype 0
|
||||
#define DB_srpverifier 1
|
||||
#define DB_srpsalt 2
|
||||
#define DB_srpid 3
|
||||
#define DB_srpgN 4
|
||||
#define DB_srpinfo 5
|
||||
#undef DB_NUMBER
|
||||
#define DB_NUMBER 6
|
||||
|
||||
#define DB_SRP_INDEX 'I'
|
||||
#define DB_SRP_VALID 'V'
|
||||
#define DB_SRP_REVOKED 'R'
|
||||
#define DB_SRP_MODIF 'v'
|
||||
|
||||
|
||||
/* see srp.c */
|
||||
char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N);
|
||||
SRP_gN *SRP_get_default_gN(const char * id) ;
|
||||
|
||||
/* server side .... */
|
||||
BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N);
|
||||
BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v);
|
||||
int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N);
|
||||
BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) ;
|
||||
|
||||
|
||||
|
||||
/* client side .... */
|
||||
BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass);
|
||||
BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g);
|
||||
BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u);
|
||||
int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N);
|
||||
|
||||
#define SRP_MINIMAL_N 1024
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
517
crypto/srp/srp_grps.h
Normal file
517
crypto/srp/srp_grps.h
Normal file
@ -0,0 +1,517 @@
|
||||
/* start of generated data */
|
||||
|
||||
static BN_ULONG bn_group_1024_value[] = {
|
||||
bn_pack4(9FC6,1D2F,C0EB,06E3),
|
||||
bn_pack4(FD51,38FE,8376,435B),
|
||||
bn_pack4(2FD4,CBF4,976E,AA9A),
|
||||
bn_pack4(68ED,BC3C,0572,6CC0),
|
||||
bn_pack4(C529,F566,660E,57EC),
|
||||
bn_pack4(8255,9B29,7BCF,1885),
|
||||
bn_pack4(CE8E,F4AD,69B1,5D49),
|
||||
bn_pack4(5DC7,D7B4,6154,D6B6),
|
||||
bn_pack4(8E49,5C1D,6089,DAD1),
|
||||
bn_pack4(E0D5,D8E2,50B9,8BE4),
|
||||
bn_pack4(383B,4813,D692,C6E0),
|
||||
bn_pack4(D674,DF74,96EA,81D3),
|
||||
bn_pack4(9EA2,314C,9C25,6576),
|
||||
bn_pack4(6072,6187,75FF,3C0B),
|
||||
bn_pack4(9C33,F80A,FA8F,C5E8),
|
||||
bn_pack4(EEAF,0AB9,ADB3,8DD6)
|
||||
};
|
||||
static BIGNUM bn_group_1024 = {
|
||||
bn_group_1024_value,
|
||||
(sizeof bn_group_1024_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_1024_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_group_1536_value[] = {
|
||||
bn_pack4(CF76,E3FE,D135,F9BB),
|
||||
bn_pack4(1518,0F93,499A,234D),
|
||||
bn_pack4(8CE7,A28C,2442,C6F3),
|
||||
bn_pack4(5A02,1FFF,5E91,479E),
|
||||
bn_pack4(7F8A,2FE9,B8B5,292E),
|
||||
bn_pack4(837C,264A,E3A9,BEB8),
|
||||
bn_pack4(E442,734A,F7CC,B7AE),
|
||||
bn_pack4(6577,2E43,7D6C,7F8C),
|
||||
bn_pack4(DB2F,D53D,24B7,C486),
|
||||
bn_pack4(6EDF,0195,3934,9627),
|
||||
bn_pack4(158B,FD3E,2B9C,8CF5),
|
||||
bn_pack4(764E,3F4B,53DD,9DA1),
|
||||
bn_pack4(4754,8381,DBC5,B1FC),
|
||||
bn_pack4(9B60,9E0B,E3BA,B63D),
|
||||
bn_pack4(8134,B1C8,B979,8914),
|
||||
bn_pack4(DF02,8A7C,EC67,F0D0),
|
||||
bn_pack4(80B6,55BB,9A22,E8DC),
|
||||
bn_pack4(1558,903B,A0D0,F843),
|
||||
bn_pack4(51C6,A94B,E460,7A29),
|
||||
bn_pack4(5F4F,5F55,6E27,CBDE),
|
||||
bn_pack4(BEEE,A961,4B19,CC4D),
|
||||
bn_pack4(DBA5,1DF4,99AC,4C80),
|
||||
bn_pack4(B1F1,2A86,17A4,7BBB),
|
||||
bn_pack4(9DEF,3CAF,B939,277A)
|
||||
};
|
||||
static BIGNUM bn_group_1536 = {
|
||||
bn_group_1536_value,
|
||||
(sizeof bn_group_1536_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_1536_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_group_2048_value[] = {
|
||||
bn_pack4(0FA7,111F,9E4A,FF73),
|
||||
bn_pack4(9B65,E372,FCD6,8EF2),
|
||||
bn_pack4(35DE,236D,525F,5475),
|
||||
bn_pack4(94B5,C803,D89F,7AE4),
|
||||
bn_pack4(71AE,35F8,E9DB,FBB6),
|
||||
bn_pack4(2A56,98F3,A8D0,C382),
|
||||
bn_pack4(9CCC,041C,7BC3,08D8),
|
||||
bn_pack4(AF87,4E73,03CE,5329),
|
||||
bn_pack4(6160,2790,04E5,7AE6),
|
||||
bn_pack4(032C,FBDB,F52F,B378),
|
||||
bn_pack4(5EA7,7A27,75D2,ECFA),
|
||||
bn_pack4(5445,23B5,24B0,D57D),
|
||||
bn_pack4(5B9D,32E6,88F8,7748),
|
||||
bn_pack4(F1D2,B907,8717,461A),
|
||||
bn_pack4(76BD,207A,436C,6481),
|
||||
bn_pack4(CA97,B43A,23FB,8016),
|
||||
bn_pack4(1D28,1E44,6B14,773B),
|
||||
bn_pack4(7359,D041,D5C3,3EA7),
|
||||
bn_pack4(A80D,740A,DBF4,FF74),
|
||||
bn_pack4(55F9,7993,EC97,5EEA),
|
||||
bn_pack4(2918,A996,2F0B,93B8),
|
||||
bn_pack4(661A,05FB,D5FA,AAE8),
|
||||
bn_pack4(CF60,9517,9A16,3AB3),
|
||||
bn_pack4(E808,3969,EDB7,67B0),
|
||||
bn_pack4(CD7F,48A9,DA04,FD50),
|
||||
bn_pack4(D523,12AB,4B03,310D),
|
||||
bn_pack4(8193,E075,7767,A13D),
|
||||
bn_pack4(A373,29CB,B4A0,99ED),
|
||||
bn_pack4(FC31,9294,3DB5,6050),
|
||||
bn_pack4(AF72,B665,1987,EE07),
|
||||
bn_pack4(F166,DE5E,1389,582F),
|
||||
bn_pack4(AC6B,DB41,324A,9A9B)
|
||||
};
|
||||
static BIGNUM bn_group_2048 = {
|
||||
bn_group_2048_value,
|
||||
(sizeof bn_group_2048_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_2048_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_group_3072_value[] = {
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF),
|
||||
bn_pack4(4B82,D120,A93A,D2CA),
|
||||
bn_pack4(43DB,5BFC,E0FD,108E),
|
||||
bn_pack4(08E2,4FA0,74E5,AB31),
|
||||
bn_pack4(7709,88C0,BAD9,46E2),
|
||||
bn_pack4(BBE1,1757,7A61,5D6C),
|
||||
bn_pack4(521F,2B18,177B,200C),
|
||||
bn_pack4(D876,0273,3EC8,6A64),
|
||||
bn_pack4(F12F,FA06,D98A,0864),
|
||||
bn_pack4(CEE3,D226,1AD2,EE6B),
|
||||
bn_pack4(1E8C,94E0,4A25,619D),
|
||||
bn_pack4(ABF5,AE8C,DB09,33D7),
|
||||
bn_pack4(B397,0F85,A6E1,E4C7),
|
||||
bn_pack4(8AEA,7157,5D06,0C7D),
|
||||
bn_pack4(ECFB,8504,58DB,EF0A),
|
||||
bn_pack4(A855,21AB,DF1C,BA64),
|
||||
bn_pack4(AD33,170D,0450,7A33),
|
||||
bn_pack4(1572,8E5A,8AAA,C42D),
|
||||
bn_pack4(15D2,2618,98FA,0510),
|
||||
bn_pack4(3995,497C,EA95,6AE5),
|
||||
bn_pack4(DE2B,CBF6,9558,1718),
|
||||
bn_pack4(B5C5,5DF0,6F4C,52C9),
|
||||
bn_pack4(9B27,83A2,EC07,A28F),
|
||||
bn_pack4(E39E,772C,180E,8603),
|
||||
bn_pack4(3290,5E46,2E36,CE3B),
|
||||
bn_pack4(F174,6C08,CA18,217C),
|
||||
bn_pack4(670C,354E,4ABC,9804),
|
||||
bn_pack4(9ED5,2907,7096,966D),
|
||||
bn_pack4(1C62,F356,2085,52BB),
|
||||
bn_pack4(8365,5D23,DCA3,AD96),
|
||||
bn_pack4(6916,3FA8,FD24,CF5F),
|
||||
bn_pack4(98DA,4836,1C55,D39A),
|
||||
bn_pack4(C200,7CB8,A163,BF05),
|
||||
bn_pack4(4928,6651,ECE4,5B3D),
|
||||
bn_pack4(AE9F,2411,7C4B,1FE6),
|
||||
bn_pack4(EE38,6BFB,5A89,9FA5),
|
||||
bn_pack4(0BFF,5CB6,F406,B7ED),
|
||||
bn_pack4(F44C,42E9,A637,ED6B),
|
||||
bn_pack4(E485,B576,625E,7EC6),
|
||||
bn_pack4(4FE1,356D,6D51,C245),
|
||||
bn_pack4(302B,0A6D,F25F,1437),
|
||||
bn_pack4(EF95,19B3,CD3A,431B),
|
||||
bn_pack4(514A,0879,8E34,04DD),
|
||||
bn_pack4(020B,BEA6,3B13,9B22),
|
||||
bn_pack4(2902,4E08,8A67,CC74),
|
||||
bn_pack4(C4C6,628B,80DC,1CD1),
|
||||
bn_pack4(C90F,DAA2,2168,C234),
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF)
|
||||
};
|
||||
static BIGNUM bn_group_3072 = {
|
||||
bn_group_3072_value,
|
||||
(sizeof bn_group_3072_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_3072_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_group_4096_value[] = {
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF),
|
||||
bn_pack4(4DF4,35C9,3406,3199),
|
||||
bn_pack4(86FF,B7DC,90A6,C08F),
|
||||
bn_pack4(93B4,EA98,8D8F,DDC1),
|
||||
bn_pack4(D006,9127,D5B0,5AA9),
|
||||
bn_pack4(B81B,DD76,2170,481C),
|
||||
bn_pack4(1F61,2970,CEE2,D7AF),
|
||||
bn_pack4(233B,A186,515B,E7ED),
|
||||
bn_pack4(99B2,964F,A090,C3A2),
|
||||
bn_pack4(287C,5947,4E6B,C05D),
|
||||
bn_pack4(2E8E,FC14,1FBE,CAA6),
|
||||
bn_pack4(DBBB,C2DB,04DE,8EF9),
|
||||
bn_pack4(2583,E9CA,2AD4,4CE8),
|
||||
bn_pack4(1A94,6834,B615,0BDA),
|
||||
bn_pack4(99C3,2718,6AF4,E23C),
|
||||
bn_pack4(8871,9A10,BDBA,5B26),
|
||||
bn_pack4(1A72,3C12,A787,E6D7),
|
||||
bn_pack4(4B82,D120,A921,0801),
|
||||
bn_pack4(43DB,5BFC,E0FD,108E),
|
||||
bn_pack4(08E2,4FA0,74E5,AB31),
|
||||
bn_pack4(7709,88C0,BAD9,46E2),
|
||||
bn_pack4(BBE1,1757,7A61,5D6C),
|
||||
bn_pack4(521F,2B18,177B,200C),
|
||||
bn_pack4(D876,0273,3EC8,6A64),
|
||||
bn_pack4(F12F,FA06,D98A,0864),
|
||||
bn_pack4(CEE3,D226,1AD2,EE6B),
|
||||
bn_pack4(1E8C,94E0,4A25,619D),
|
||||
bn_pack4(ABF5,AE8C,DB09,33D7),
|
||||
bn_pack4(B397,0F85,A6E1,E4C7),
|
||||
bn_pack4(8AEA,7157,5D06,0C7D),
|
||||
bn_pack4(ECFB,8504,58DB,EF0A),
|
||||
bn_pack4(A855,21AB,DF1C,BA64),
|
||||
bn_pack4(AD33,170D,0450,7A33),
|
||||
bn_pack4(1572,8E5A,8AAA,C42D),
|
||||
bn_pack4(15D2,2618,98FA,0510),
|
||||
bn_pack4(3995,497C,EA95,6AE5),
|
||||
bn_pack4(DE2B,CBF6,9558,1718),
|
||||
bn_pack4(B5C5,5DF0,6F4C,52C9),
|
||||
bn_pack4(9B27,83A2,EC07,A28F),
|
||||
bn_pack4(E39E,772C,180E,8603),
|
||||
bn_pack4(3290,5E46,2E36,CE3B),
|
||||
bn_pack4(F174,6C08,CA18,217C),
|
||||
bn_pack4(670C,354E,4ABC,9804),
|
||||
bn_pack4(9ED5,2907,7096,966D),
|
||||
bn_pack4(1C62,F356,2085,52BB),
|
||||
bn_pack4(8365,5D23,DCA3,AD96),
|
||||
bn_pack4(6916,3FA8,FD24,CF5F),
|
||||
bn_pack4(98DA,4836,1C55,D39A),
|
||||
bn_pack4(C200,7CB8,A163,BF05),
|
||||
bn_pack4(4928,6651,ECE4,5B3D),
|
||||
bn_pack4(AE9F,2411,7C4B,1FE6),
|
||||
bn_pack4(EE38,6BFB,5A89,9FA5),
|
||||
bn_pack4(0BFF,5CB6,F406,B7ED),
|
||||
bn_pack4(F44C,42E9,A637,ED6B),
|
||||
bn_pack4(E485,B576,625E,7EC6),
|
||||
bn_pack4(4FE1,356D,6D51,C245),
|
||||
bn_pack4(302B,0A6D,F25F,1437),
|
||||
bn_pack4(EF95,19B3,CD3A,431B),
|
||||
bn_pack4(514A,0879,8E34,04DD),
|
||||
bn_pack4(020B,BEA6,3B13,9B22),
|
||||
bn_pack4(2902,4E08,8A67,CC74),
|
||||
bn_pack4(C4C6,628B,80DC,1CD1),
|
||||
bn_pack4(C90F,DAA2,2168,C234),
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF)
|
||||
};
|
||||
static BIGNUM bn_group_4096 = {
|
||||
bn_group_4096_value,
|
||||
(sizeof bn_group_4096_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_4096_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_group_6144_value[] = {
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF),
|
||||
bn_pack4(E694,F91E,6DCC,4024),
|
||||
bn_pack4(12BF,2D5B,0B74,74D6),
|
||||
bn_pack4(043E,8F66,3F48,60EE),
|
||||
bn_pack4(387F,E8D7,6E3C,0468),
|
||||
bn_pack4(DA56,C9EC,2EF2,9632),
|
||||
bn_pack4(EB19,CCB1,A313,D55C),
|
||||
bn_pack4(F550,AA3D,8A1F,BFF0),
|
||||
bn_pack4(06A1,D58B,B7C5,DA76),
|
||||
bn_pack4(A797,15EE,F29B,E328),
|
||||
bn_pack4(14CC,5ED2,0F80,37E0),
|
||||
bn_pack4(CC8F,6D7E,BF48,E1D8),
|
||||
bn_pack4(4BD4,07B2,2B41,54AA),
|
||||
bn_pack4(0F1D,45B7,FF58,5AC5),
|
||||
bn_pack4(23A9,7A7E,36CC,88BE),
|
||||
bn_pack4(59E7,C97F,BEC7,E8F3),
|
||||
bn_pack4(B5A8,4031,900B,1C9E),
|
||||
bn_pack4(D55E,702F,4698,0C82),
|
||||
bn_pack4(F482,D7CE,6E74,FEF6),
|
||||
bn_pack4(F032,EA15,D172,1D03),
|
||||
bn_pack4(5983,CA01,C64B,92EC),
|
||||
bn_pack4(6FB8,F401,378C,D2BF),
|
||||
bn_pack4(3320,5151,2BD7,AF42),
|
||||
bn_pack4(DB7F,1447,E6CC,254B),
|
||||
bn_pack4(44CE,6CBA,CED4,BB1B),
|
||||
bn_pack4(DA3E,DBEB,CF9B,14ED),
|
||||
bn_pack4(1797,27B0,865A,8918),
|
||||
bn_pack4(B06A,53ED,9027,D831),
|
||||
bn_pack4(E5DB,382F,4130,01AE),
|
||||
bn_pack4(F8FF,9406,AD9E,530E),
|
||||
bn_pack4(C975,1E76,3DBA,37BD),
|
||||
bn_pack4(C1D4,DCB2,6026,46DE),
|
||||
bn_pack4(36C3,FAB4,D27C,7026),
|
||||
bn_pack4(4DF4,35C9,3402,8492),
|
||||
bn_pack4(86FF,B7DC,90A6,C08F),
|
||||
bn_pack4(93B4,EA98,8D8F,DDC1),
|
||||
bn_pack4(D006,9127,D5B0,5AA9),
|
||||
bn_pack4(B81B,DD76,2170,481C),
|
||||
bn_pack4(1F61,2970,CEE2,D7AF),
|
||||
bn_pack4(233B,A186,515B,E7ED),
|
||||
bn_pack4(99B2,964F,A090,C3A2),
|
||||
bn_pack4(287C,5947,4E6B,C05D),
|
||||
bn_pack4(2E8E,FC14,1FBE,CAA6),
|
||||
bn_pack4(DBBB,C2DB,04DE,8EF9),
|
||||
bn_pack4(2583,E9CA,2AD4,4CE8),
|
||||
bn_pack4(1A94,6834,B615,0BDA),
|
||||
bn_pack4(99C3,2718,6AF4,E23C),
|
||||
bn_pack4(8871,9A10,BDBA,5B26),
|
||||
bn_pack4(1A72,3C12,A787,E6D7),
|
||||
bn_pack4(4B82,D120,A921,0801),
|
||||
bn_pack4(43DB,5BFC,E0FD,108E),
|
||||
bn_pack4(08E2,4FA0,74E5,AB31),
|
||||
bn_pack4(7709,88C0,BAD9,46E2),
|
||||
bn_pack4(BBE1,1757,7A61,5D6C),
|
||||
bn_pack4(521F,2B18,177B,200C),
|
||||
bn_pack4(D876,0273,3EC8,6A64),
|
||||
bn_pack4(F12F,FA06,D98A,0864),
|
||||
bn_pack4(CEE3,D226,1AD2,EE6B),
|
||||
bn_pack4(1E8C,94E0,4A25,619D),
|
||||
bn_pack4(ABF5,AE8C,DB09,33D7),
|
||||
bn_pack4(B397,0F85,A6E1,E4C7),
|
||||
bn_pack4(8AEA,7157,5D06,0C7D),
|
||||
bn_pack4(ECFB,8504,58DB,EF0A),
|
||||
bn_pack4(A855,21AB,DF1C,BA64),
|
||||
bn_pack4(AD33,170D,0450,7A33),
|
||||
bn_pack4(1572,8E5A,8AAA,C42D),
|
||||
bn_pack4(15D2,2618,98FA,0510),
|
||||
bn_pack4(3995,497C,EA95,6AE5),
|
||||
bn_pack4(DE2B,CBF6,9558,1718),
|
||||
bn_pack4(B5C5,5DF0,6F4C,52C9),
|
||||
bn_pack4(9B27,83A2,EC07,A28F),
|
||||
bn_pack4(E39E,772C,180E,8603),
|
||||
bn_pack4(3290,5E46,2E36,CE3B),
|
||||
bn_pack4(F174,6C08,CA18,217C),
|
||||
bn_pack4(670C,354E,4ABC,9804),
|
||||
bn_pack4(9ED5,2907,7096,966D),
|
||||
bn_pack4(1C62,F356,2085,52BB),
|
||||
bn_pack4(8365,5D23,DCA3,AD96),
|
||||
bn_pack4(6916,3FA8,FD24,CF5F),
|
||||
bn_pack4(98DA,4836,1C55,D39A),
|
||||
bn_pack4(C200,7CB8,A163,BF05),
|
||||
bn_pack4(4928,6651,ECE4,5B3D),
|
||||
bn_pack4(AE9F,2411,7C4B,1FE6),
|
||||
bn_pack4(EE38,6BFB,5A89,9FA5),
|
||||
bn_pack4(0BFF,5CB6,F406,B7ED),
|
||||
bn_pack4(F44C,42E9,A637,ED6B),
|
||||
bn_pack4(E485,B576,625E,7EC6),
|
||||
bn_pack4(4FE1,356D,6D51,C245),
|
||||
bn_pack4(302B,0A6D,F25F,1437),
|
||||
bn_pack4(EF95,19B3,CD3A,431B),
|
||||
bn_pack4(514A,0879,8E34,04DD),
|
||||
bn_pack4(020B,BEA6,3B13,9B22),
|
||||
bn_pack4(2902,4E08,8A67,CC74),
|
||||
bn_pack4(C4C6,628B,80DC,1CD1),
|
||||
bn_pack4(C90F,DAA2,2168,C234),
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF)
|
||||
};
|
||||
static BIGNUM bn_group_6144 = {
|
||||
bn_group_6144_value,
|
||||
(sizeof bn_group_6144_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_6144_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_group_8192_value[] = {
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF),
|
||||
bn_pack4(60C9,80DD,98ED,D3DF),
|
||||
bn_pack4(C81F,56E8,80B9,6E71),
|
||||
bn_pack4(9E30,50E2,7656,94DF),
|
||||
bn_pack4(9558,E447,5677,E9AA),
|
||||
bn_pack4(C919,0DA6,FC02,6E47),
|
||||
bn_pack4(889A,002E,D5EE,382B),
|
||||
bn_pack4(4009,438B,481C,6CD7),
|
||||
bn_pack4(3590,46F4,EB87,9F92),
|
||||
bn_pack4(FAF3,6BC3,1ECF,A268),
|
||||
bn_pack4(B1D5,10BD,7EE7,4D73),
|
||||
bn_pack4(F9AB,4819,5DED,7EA1),
|
||||
bn_pack4(64F3,1CC5,0846,851D),
|
||||
bn_pack4(4597,E899,A025,5DC1),
|
||||
bn_pack4(DF31,0EE0,74AB,6A36),
|
||||
bn_pack4(6D2A,13F8,3F44,F82D),
|
||||
bn_pack4(062B,3CF5,B3A2,78A6),
|
||||
bn_pack4(7968,3303,ED5B,DD3A),
|
||||
bn_pack4(FA9D,4B7F,A2C0,87E8),
|
||||
bn_pack4(4BCB,C886,2F83,85DD),
|
||||
bn_pack4(3473,FC64,6CEA,306B),
|
||||
bn_pack4(13EB,57A8,1A23,F0C7),
|
||||
bn_pack4(2222,2E04,A403,7C07),
|
||||
bn_pack4(E3FD,B8BE,FC84,8AD9),
|
||||
bn_pack4(238F,16CB,E39D,652D),
|
||||
bn_pack4(3423,B474,2BF1,C978),
|
||||
bn_pack4(3AAB,639C,5AE4,F568),
|
||||
bn_pack4(2576,F693,6BA4,2466),
|
||||
bn_pack4(741F,A7BF,8AFC,47ED),
|
||||
bn_pack4(3BC8,32B6,8D9D,D300),
|
||||
bn_pack4(D8BE,C4D0,73B9,31BA),
|
||||
bn_pack4(3877,7CB6,A932,DF8C),
|
||||
bn_pack4(74A3,926F,12FE,E5E4),
|
||||
bn_pack4(E694,F91E,6DBE,1159),
|
||||
bn_pack4(12BF,2D5B,0B74,74D6),
|
||||
bn_pack4(043E,8F66,3F48,60EE),
|
||||
bn_pack4(387F,E8D7,6E3C,0468),
|
||||
bn_pack4(DA56,C9EC,2EF2,9632),
|
||||
bn_pack4(EB19,CCB1,A313,D55C),
|
||||
bn_pack4(F550,AA3D,8A1F,BFF0),
|
||||
bn_pack4(06A1,D58B,B7C5,DA76),
|
||||
bn_pack4(A797,15EE,F29B,E328),
|
||||
bn_pack4(14CC,5ED2,0F80,37E0),
|
||||
bn_pack4(CC8F,6D7E,BF48,E1D8),
|
||||
bn_pack4(4BD4,07B2,2B41,54AA),
|
||||
bn_pack4(0F1D,45B7,FF58,5AC5),
|
||||
bn_pack4(23A9,7A7E,36CC,88BE),
|
||||
bn_pack4(59E7,C97F,BEC7,E8F3),
|
||||
bn_pack4(B5A8,4031,900B,1C9E),
|
||||
bn_pack4(D55E,702F,4698,0C82),
|
||||
bn_pack4(F482,D7CE,6E74,FEF6),
|
||||
bn_pack4(F032,EA15,D172,1D03),
|
||||
bn_pack4(5983,CA01,C64B,92EC),
|
||||
bn_pack4(6FB8,F401,378C,D2BF),
|
||||
bn_pack4(3320,5151,2BD7,AF42),
|
||||
bn_pack4(DB7F,1447,E6CC,254B),
|
||||
bn_pack4(44CE,6CBA,CED4,BB1B),
|
||||
bn_pack4(DA3E,DBEB,CF9B,14ED),
|
||||
bn_pack4(1797,27B0,865A,8918),
|
||||
bn_pack4(B06A,53ED,9027,D831),
|
||||
bn_pack4(E5DB,382F,4130,01AE),
|
||||
bn_pack4(F8FF,9406,AD9E,530E),
|
||||
bn_pack4(C975,1E76,3DBA,37BD),
|
||||
bn_pack4(C1D4,DCB2,6026,46DE),
|
||||
bn_pack4(36C3,FAB4,D27C,7026),
|
||||
bn_pack4(4DF4,35C9,3402,8492),
|
||||
bn_pack4(86FF,B7DC,90A6,C08F),
|
||||
bn_pack4(93B4,EA98,8D8F,DDC1),
|
||||
bn_pack4(D006,9127,D5B0,5AA9),
|
||||
bn_pack4(B81B,DD76,2170,481C),
|
||||
bn_pack4(1F61,2970,CEE2,D7AF),
|
||||
bn_pack4(233B,A186,515B,E7ED),
|
||||
bn_pack4(99B2,964F,A090,C3A2),
|
||||
bn_pack4(287C,5947,4E6B,C05D),
|
||||
bn_pack4(2E8E,FC14,1FBE,CAA6),
|
||||
bn_pack4(DBBB,C2DB,04DE,8EF9),
|
||||
bn_pack4(2583,E9CA,2AD4,4CE8),
|
||||
bn_pack4(1A94,6834,B615,0BDA),
|
||||
bn_pack4(99C3,2718,6AF4,E23C),
|
||||
bn_pack4(8871,9A10,BDBA,5B26),
|
||||
bn_pack4(1A72,3C12,A787,E6D7),
|
||||
bn_pack4(4B82,D120,A921,0801),
|
||||
bn_pack4(43DB,5BFC,E0FD,108E),
|
||||
bn_pack4(08E2,4FA0,74E5,AB31),
|
||||
bn_pack4(7709,88C0,BAD9,46E2),
|
||||
bn_pack4(BBE1,1757,7A61,5D6C),
|
||||
bn_pack4(521F,2B18,177B,200C),
|
||||
bn_pack4(D876,0273,3EC8,6A64),
|
||||
bn_pack4(F12F,FA06,D98A,0864),
|
||||
bn_pack4(CEE3,D226,1AD2,EE6B),
|
||||
bn_pack4(1E8C,94E0,4A25,619D),
|
||||
bn_pack4(ABF5,AE8C,DB09,33D7),
|
||||
bn_pack4(B397,0F85,A6E1,E4C7),
|
||||
bn_pack4(8AEA,7157,5D06,0C7D),
|
||||
bn_pack4(ECFB,8504,58DB,EF0A),
|
||||
bn_pack4(A855,21AB,DF1C,BA64),
|
||||
bn_pack4(AD33,170D,0450,7A33),
|
||||
bn_pack4(1572,8E5A,8AAA,C42D),
|
||||
bn_pack4(15D2,2618,98FA,0510),
|
||||
bn_pack4(3995,497C,EA95,6AE5),
|
||||
bn_pack4(DE2B,CBF6,9558,1718),
|
||||
bn_pack4(B5C5,5DF0,6F4C,52C9),
|
||||
bn_pack4(9B27,83A2,EC07,A28F),
|
||||
bn_pack4(E39E,772C,180E,8603),
|
||||
bn_pack4(3290,5E46,2E36,CE3B),
|
||||
bn_pack4(F174,6C08,CA18,217C),
|
||||
bn_pack4(670C,354E,4ABC,9804),
|
||||
bn_pack4(9ED5,2907,7096,966D),
|
||||
bn_pack4(1C62,F356,2085,52BB),
|
||||
bn_pack4(8365,5D23,DCA3,AD96),
|
||||
bn_pack4(6916,3FA8,FD24,CF5F),
|
||||
bn_pack4(98DA,4836,1C55,D39A),
|
||||
bn_pack4(C200,7CB8,A163,BF05),
|
||||
bn_pack4(4928,6651,ECE4,5B3D),
|
||||
bn_pack4(AE9F,2411,7C4B,1FE6),
|
||||
bn_pack4(EE38,6BFB,5A89,9FA5),
|
||||
bn_pack4(0BFF,5CB6,F406,B7ED),
|
||||
bn_pack4(F44C,42E9,A637,ED6B),
|
||||
bn_pack4(E485,B576,625E,7EC6),
|
||||
bn_pack4(4FE1,356D,6D51,C245),
|
||||
bn_pack4(302B,0A6D,F25F,1437),
|
||||
bn_pack4(EF95,19B3,CD3A,431B),
|
||||
bn_pack4(514A,0879,8E34,04DD),
|
||||
bn_pack4(020B,BEA6,3B13,9B22),
|
||||
bn_pack4(2902,4E08,8A67,CC74),
|
||||
bn_pack4(C4C6,628B,80DC,1CD1),
|
||||
bn_pack4(C90F,DAA2,2168,C234),
|
||||
bn_pack4(FFFF,FFFF,FFFF,FFFF)
|
||||
};
|
||||
static BIGNUM bn_group_8192 = {
|
||||
bn_group_8192_value,
|
||||
(sizeof bn_group_8192_value)/sizeof(BN_ULONG),
|
||||
(sizeof bn_group_8192_value)/sizeof(BN_ULONG),
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static BN_ULONG bn_generator_19_value[] = {19} ;
|
||||
static BIGNUM bn_generator_19 = {
|
||||
bn_generator_19_value,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
static BN_ULONG bn_generator_5_value[] = {5} ;
|
||||
static BIGNUM bn_generator_5 = {
|
||||
bn_generator_5_value,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
static BN_ULONG bn_generator_2_value[] = {2} ;
|
||||
static BIGNUM bn_generator_2 = {
|
||||
bn_generator_2_value,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
BN_FLG_STATIC_DATA
|
||||
};
|
||||
|
||||
static SRP_gN knowngN[] = {
|
||||
{"8192",&bn_generator_19 , &bn_group_8192},
|
||||
{"6144",&bn_generator_5 , &bn_group_6144},
|
||||
{"4096",&bn_generator_5 , &bn_group_4096},
|
||||
{"3072",&bn_generator_5 , &bn_group_3072},
|
||||
{"2048",&bn_generator_2 , &bn_group_2048},
|
||||
{"1536",&bn_generator_2 , &bn_group_1536},
|
||||
{"1024",&bn_generator_2 , &bn_group_1024},
|
||||
};
|
||||
#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
|
||||
|
||||
/* end of generated data */
|
83
crypto/srp/srp_lcl.h
Normal file
83
crypto/srp/srp_lcl.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* crypto/srp/srp_lcl.h */
|
||||
/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#ifndef HEADER_SRP_LCL_H
|
||||
#define HEADER_SRP_LCL_H
|
||||
|
||||
#include <openssl/srp.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#if 0
|
||||
#define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
|
||||
fprintf(stderr,"\n");}
|
||||
#else
|
||||
#define srp_bn_print(a)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
357
crypto/srp/srp_lib.c
Normal file
357
crypto/srp/srp_lib.c
Normal file
@ -0,0 +1,357 @@
|
||||
/* crypto/srp/srp_lib.c */
|
||||
/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
|
||||
* the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include "cryptlib.h"
|
||||
#include "srp_lcl.h"
|
||||
#include <openssl/srp.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#if (BN_BYTES == 8)
|
||||
#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul
|
||||
#endif
|
||||
#if (BN_BYTES == 4)
|
||||
#define bn_pack4(a1,a2,a3,a4) 0x##a3##a4##ul, 0x##a1##a2##ul
|
||||
#endif
|
||||
#if (BN_BYTES == 2)
|
||||
#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u
|
||||
#endif
|
||||
|
||||
|
||||
#include "srp_grps.h"
|
||||
|
||||
static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
|
||||
{
|
||||
/* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
|
||||
|
||||
unsigned char digest[SHA_DIGEST_LENGTH];
|
||||
unsigned char *tmp;
|
||||
EVP_MD_CTX ctxt;
|
||||
int longg ;
|
||||
int longN = BN_num_bytes(N);
|
||||
|
||||
if ((tmp = OPENSSL_malloc(longN)) == NULL)
|
||||
return NULL;
|
||||
BN_bn2bin(N,tmp) ;
|
||||
|
||||
EVP_MD_CTX_init(&ctxt);
|
||||
EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(&ctxt, tmp, longN);
|
||||
|
||||
memset(tmp, 0, longN);
|
||||
longg = BN_bn2bin(g,tmp) ;
|
||||
/* use the zeros behind to pad on left */
|
||||
EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg);
|
||||
EVP_DigestUpdate(&ctxt, tmp, longg);
|
||||
OPENSSL_free(tmp);
|
||||
|
||||
EVP_DigestFinal_ex(&ctxt, digest, NULL);
|
||||
EVP_MD_CTX_cleanup(&ctxt);
|
||||
return BN_bin2bn(digest, sizeof(digest), NULL);
|
||||
}
|
||||
|
||||
BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
|
||||
{
|
||||
/* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
|
||||
|
||||
BIGNUM *u;
|
||||
unsigned char cu[SHA_DIGEST_LENGTH];
|
||||
unsigned char *cAB;
|
||||
EVP_MD_CTX ctxt;
|
||||
int longN;
|
||||
if ((A == NULL) ||(B == NULL) || (N == NULL))
|
||||
return NULL;
|
||||
|
||||
longN= BN_num_bytes(N);
|
||||
|
||||
if ((cAB = OPENSSL_malloc(2*longN)) == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(cAB, 0, longN);
|
||||
|
||||
EVP_MD_CTX_init(&ctxt);
|
||||
EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN);
|
||||
EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN);
|
||||
OPENSSL_free(cAB);
|
||||
EVP_DigestFinal_ex(&ctxt, cu, NULL);
|
||||
EVP_MD_CTX_cleanup(&ctxt);
|
||||
|
||||
if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
|
||||
return NULL;
|
||||
if (!BN_is_zero(u))
|
||||
return u;
|
||||
BN_free(u);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N)
|
||||
{
|
||||
BIGNUM *tmp = NULL, *S = NULL;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL ||
|
||||
(tmp = BN_new()) == NULL ||
|
||||
(S = BN_new()) == NULL )
|
||||
goto err;
|
||||
|
||||
/* S = (A*v**u) ** b */
|
||||
|
||||
if (!BN_mod_exp(tmp,v,u,N,bn_ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx))
|
||||
goto err;
|
||||
if (!BN_mod_exp(S,tmp,b,N,bn_ctx))
|
||||
goto err;
|
||||
err:
|
||||
BN_CTX_free(bn_ctx);
|
||||
BN_clear_free(tmp);
|
||||
return S;
|
||||
}
|
||||
|
||||
BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
|
||||
{
|
||||
BIGNUM *kv = NULL, *gb = NULL;
|
||||
BIGNUM *B = NULL, *k = NULL;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
if (b == NULL || N == NULL || g == NULL || v == NULL ||
|
||||
(bn_ctx = BN_CTX_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ( (kv = BN_new()) == NULL ||
|
||||
(gb = BN_new()) == NULL ||
|
||||
(B = BN_new())== NULL)
|
||||
goto err;
|
||||
|
||||
/* B = g**b + k*v */
|
||||
|
||||
if (!BN_mod_exp(gb,g,b,N,bn_ctx) ||
|
||||
!(k = srp_Calc_k(N,g)) ||
|
||||
!BN_mod_mul(kv,v,k,N,bn_ctx) ||
|
||||
!BN_mod_add(B,gb,kv,N,bn_ctx))
|
||||
{
|
||||
BN_free(B);
|
||||
B = NULL;
|
||||
}
|
||||
err:
|
||||
BN_CTX_free(bn_ctx);
|
||||
BN_clear_free(kv);
|
||||
BN_clear_free(gb);
|
||||
BN_free(k);
|
||||
return B;
|
||||
}
|
||||
|
||||
BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
|
||||
{
|
||||
unsigned char dig[SHA_DIGEST_LENGTH];
|
||||
EVP_MD_CTX ctxt;
|
||||
unsigned char *cs;
|
||||
|
||||
if ((s == NULL) ||
|
||||
(user == NULL) ||
|
||||
(pass == NULL))
|
||||
return NULL;
|
||||
|
||||
if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
|
||||
return NULL;
|
||||
|
||||
EVP_MD_CTX_init(&ctxt);
|
||||
EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(&ctxt, user, strlen(user));
|
||||
EVP_DigestUpdate(&ctxt, ":", 1);
|
||||
EVP_DigestUpdate(&ctxt, pass, strlen(pass));
|
||||
EVP_DigestFinal_ex(&ctxt, dig, NULL);
|
||||
|
||||
EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
|
||||
BN_bn2bin(s,cs);
|
||||
EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
|
||||
OPENSSL_free(cs);
|
||||
EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
|
||||
EVP_DigestFinal_ex(&ctxt, dig, NULL);
|
||||
EVP_MD_CTX_cleanup(&ctxt);
|
||||
|
||||
return BN_bin2bn(dig, sizeof(dig), NULL);
|
||||
}
|
||||
|
||||
BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
|
||||
{
|
||||
BN_CTX *bn_ctx;
|
||||
BIGNUM * A = NULL;
|
||||
|
||||
if (a == NULL || N == NULL || g == NULL ||
|
||||
(bn_ctx = BN_CTX_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((A = BN_new()) != NULL &&
|
||||
!BN_mod_exp(A,g,a,N,bn_ctx))
|
||||
{
|
||||
BN_free(A);
|
||||
A = NULL;
|
||||
}
|
||||
BN_CTX_free(bn_ctx);
|
||||
return A;
|
||||
}
|
||||
|
||||
|
||||
BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u)
|
||||
{
|
||||
BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL ||
|
||||
(bn_ctx = BN_CTX_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((tmp = BN_new()) == NULL ||
|
||||
(tmp2 = BN_new())== NULL ||
|
||||
(tmp3 = BN_new())== NULL ||
|
||||
(K = BN_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_mod_exp(tmp,g,x,N,bn_ctx))
|
||||
goto err;
|
||||
if (!(k = srp_Calc_k(N,g)))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx))
|
||||
goto err;
|
||||
if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_mod_mul(tmp3,u,x,N,bn_ctx))
|
||||
goto err;
|
||||
if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx))
|
||||
goto err;
|
||||
if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx))
|
||||
goto err;
|
||||
|
||||
err :
|
||||
BN_CTX_free(bn_ctx);
|
||||
BN_clear_free(tmp);
|
||||
BN_clear_free(tmp2);
|
||||
BN_clear_free(tmp3);
|
||||
BN_free(k);
|
||||
return K;
|
||||
}
|
||||
|
||||
int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
|
||||
{
|
||||
BIGNUM *r;
|
||||
BN_CTX *bn_ctx;
|
||||
int ret = 0;
|
||||
|
||||
if (B == NULL || N == NULL ||
|
||||
(bn_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((r = BN_new()) == NULL)
|
||||
goto err;
|
||||
/* Checks if B % N == 0 */
|
||||
if (!BN_nnmod(r,B,N,bn_ctx))
|
||||
goto err;
|
||||
ret = !BN_is_zero(r);
|
||||
err:
|
||||
BN_CTX_free(bn_ctx);
|
||||
BN_free(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
|
||||
{
|
||||
/* Checks if A % N == 0 */
|
||||
return SRP_Verify_B_mod_N(A,N) ;
|
||||
}
|
||||
|
||||
|
||||
/* Check if G and N are kwown parameters.
|
||||
The values have been generated from the ietf-tls-srp draft version 8
|
||||
*/
|
||||
char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)
|
||||
{
|
||||
size_t i;
|
||||
if ((g == NULL) || (N == NULL))
|
||||
return 0;
|
||||
|
||||
srp_bn_print(g);
|
||||
srp_bn_print(N);
|
||||
|
||||
for(i = 0; i < KNOWN_GN_NUMBER; i++)
|
||||
{
|
||||
if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)
|
||||
return knowngN[i].id;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRP_gN *SRP_get_default_gN(const char *id)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (id == NULL)
|
||||
return knowngN;
|
||||
for(i = 0; i < KNOWN_GN_NUMBER; i++)
|
||||
{
|
||||
if (strcmp(knowngN[i].id, id)==0)
|
||||
return knowngN + i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
657
crypto/srp/srp_vfy.c
Normal file
657
crypto/srp/srp_vfy.c
Normal file
@ -0,0 +1,657 @@
|
||||
/* crypto/srp/srp_vfy.c */
|
||||
/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
|
||||
* the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include "cryptlib.h"
|
||||
#include "srp_lcl.h"
|
||||
#include <openssl/srp.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/txt_db.h>
|
||||
|
||||
#define SRP_RANDOM_SALT_LEN 20
|
||||
#define MAX_LEN 2500
|
||||
|
||||
static char b64table[] =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
|
||||
|
||||
/* the following two conversion routines have been inspired by code from Stanford */
|
||||
|
||||
/*
|
||||
* Convert a base64 string into raw byte array representation.
|
||||
*/
|
||||
static int t_fromb64(unsigned char *a, const char *src)
|
||||
{
|
||||
char *loc;
|
||||
int i, j;
|
||||
int size;
|
||||
|
||||
while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
|
||||
++src;
|
||||
size = strlen(src);
|
||||
i = 0;
|
||||
while(i < size)
|
||||
{
|
||||
loc = strchr(b64table, src[i]);
|
||||
if(loc == (char *) 0) break;
|
||||
else a[i] = loc - b64table;
|
||||
++i;
|
||||
}
|
||||
size = i;
|
||||
i = size - 1;
|
||||
j = size;
|
||||
while(1)
|
||||
{
|
||||
a[j] = a[i];
|
||||
if(--i < 0) break;
|
||||
a[j] |= (a[i] & 3) << 6;
|
||||
--j;
|
||||
a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
|
||||
if(--i < 0) break;
|
||||
a[j] |= (a[i] & 0xf) << 4;
|
||||
--j;
|
||||
a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
|
||||
if(--i < 0) break;
|
||||
a[j] |= (a[i] << 2);
|
||||
|
||||
a[--j] = 0;
|
||||
if(--i < 0) break;
|
||||
}
|
||||
while(a[j] == 0 && j <= size) ++j;
|
||||
i = 0;
|
||||
while (j <= size) a[i++] = a[j++];
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert a raw byte string into a null-terminated base64 ASCII string.
|
||||
*/
|
||||
static char *t_tob64(char *dst, const unsigned char *src, int size)
|
||||
{
|
||||
int c, pos = size % 3;
|
||||
unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
|
||||
char *olddst = dst;
|
||||
|
||||
switch(pos)
|
||||
{
|
||||
case 1:
|
||||
b2 = src[0];
|
||||
break;
|
||||
case 2:
|
||||
b1 = src[0];
|
||||
b2 = src[1];
|
||||
break;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
c = (b0 & 0xfc) >> 2;
|
||||
if(notleading || c != 0)
|
||||
{
|
||||
*dst++ = b64table[c];
|
||||
notleading = 1;
|
||||
}
|
||||
c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
|
||||
if(notleading || c != 0)
|
||||
{
|
||||
*dst++ = b64table[c];
|
||||
notleading = 1;
|
||||
}
|
||||
c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
|
||||
if(notleading || c != 0)
|
||||
{
|
||||
*dst++ = b64table[c];
|
||||
notleading = 1;
|
||||
}
|
||||
c = b2 & 0x3f;
|
||||
if(notleading || c != 0)
|
||||
{
|
||||
*dst++ = b64table[c];
|
||||
notleading = 1;
|
||||
}
|
||||
if(pos >= size) break;
|
||||
else
|
||||
{
|
||||
b0 = src[pos++];
|
||||
b1 = src[pos++];
|
||||
b2 = src[pos++];
|
||||
}
|
||||
}
|
||||
|
||||
*dst++ = '\0';
|
||||
return olddst;
|
||||
}
|
||||
|
||||
static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
|
||||
{
|
||||
if (user_pwd == NULL)
|
||||
return;
|
||||
BN_free(user_pwd->s);
|
||||
BN_clear_free(user_pwd->v);
|
||||
OPENSSL_free(user_pwd->id);
|
||||
OPENSSL_free(user_pwd->info);
|
||||
OPENSSL_free(user_pwd);
|
||||
}
|
||||
|
||||
static SRP_user_pwd *SRP_user_pwd_new()
|
||||
{
|
||||
SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd));
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
ret->N = NULL;
|
||||
ret->g = NULL;
|
||||
ret->s = NULL;
|
||||
ret->v = NULL;
|
||||
ret->id = NULL ;
|
||||
ret->info = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
|
||||
const BIGNUM *N)
|
||||
{
|
||||
vinfo->N = N;
|
||||
vinfo->g = g;
|
||||
}
|
||||
|
||||
static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
|
||||
const char *info)
|
||||
{
|
||||
if (id != NULL && NULL == (vinfo->id = BUF_strdup(id)))
|
||||
return 0;
|
||||
return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))) ;
|
||||
}
|
||||
|
||||
static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
|
||||
const char *v)
|
||||
{
|
||||
unsigned char tmp[MAX_LEN];
|
||||
int len;
|
||||
|
||||
if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN)
|
||||
return 0;
|
||||
len = t_fromb64(tmp, v);
|
||||
if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)) )
|
||||
return 0;
|
||||
len = t_fromb64(tmp, s);
|
||||
return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL) ;
|
||||
}
|
||||
|
||||
static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
|
||||
{
|
||||
vinfo->v = v;
|
||||
vinfo->s = s;
|
||||
return (vinfo->s != NULL && vinfo->v != NULL) ;
|
||||
}
|
||||
|
||||
SRP_VBASE *SRP_VBASE_new(char *seed_key)
|
||||
{
|
||||
SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE));
|
||||
|
||||
if (vb == NULL)
|
||||
return NULL;
|
||||
if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) ||
|
||||
!(vb->gN_cache = sk_SRP_gN_cache_new_null()))
|
||||
{
|
||||
OPENSSL_free(vb);
|
||||
return NULL;
|
||||
}
|
||||
vb->default_g = NULL;
|
||||
vb->default_N = NULL;
|
||||
vb->seed_key = NULL;
|
||||
if ((seed_key != NULL) &&
|
||||
(vb->seed_key = BUF_strdup(seed_key)) == NULL)
|
||||
{
|
||||
sk_SRP_user_pwd_free(vb->users_pwd);
|
||||
sk_SRP_gN_cache_free(vb->gN_cache);
|
||||
OPENSSL_free(vb);
|
||||
return NULL;
|
||||
}
|
||||
return vb;
|
||||
}
|
||||
|
||||
|
||||
int SRP_VBASE_free(SRP_VBASE *vb)
|
||||
{
|
||||
sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free);
|
||||
sk_SRP_gN_cache_free(vb->gN_cache);
|
||||
OPENSSL_free(vb->seed_key);
|
||||
OPENSSL_free(vb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static SRP_gN_cache *SRP_gN_new_init(const char *ch)
|
||||
{
|
||||
unsigned char tmp[MAX_LEN];
|
||||
int len;
|
||||
|
||||
SRP_gN_cache *newgN = (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache));
|
||||
if (newgN == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((newgN->b64_bn = BUF_strdup(ch)) == NULL)
|
||||
goto err;
|
||||
|
||||
len = t_fromb64(tmp, ch);
|
||||
if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
|
||||
return newgN;
|
||||
|
||||
OPENSSL_free(newgN->b64_bn);
|
||||
err:
|
||||
OPENSSL_free(newgN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void SRP_gN_free(SRP_gN_cache *gN_cache)
|
||||
{
|
||||
if (gN_cache == NULL)
|
||||
return;
|
||||
OPENSSL_free(gN_cache->b64_bn);
|
||||
BN_free(gN_cache->bn);
|
||||
OPENSSL_free(gN_cache);
|
||||
}
|
||||
|
||||
static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
|
||||
{
|
||||
int i;
|
||||
|
||||
SRP_gN *gN;
|
||||
if (gN_tab != NULL)
|
||||
for(i = 0; i < sk_SRP_gN_num(gN_tab); i++)
|
||||
{
|
||||
gN = sk_SRP_gN_value(gN_tab, i);
|
||||
if (gN && (id == NULL || strcmp(gN->id,id)==0))
|
||||
return gN;
|
||||
}
|
||||
|
||||
return SRP_get_default_gN(id);
|
||||
}
|
||||
|
||||
static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
|
||||
{
|
||||
int i;
|
||||
if (gN_cache == NULL)
|
||||
return NULL;
|
||||
|
||||
/* search if we have already one... */
|
||||
for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++)
|
||||
{
|
||||
SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
|
||||
if (strcmp(cache->b64_bn,ch)==0)
|
||||
return cache->bn;
|
||||
}
|
||||
{ /* it is the first time that we find it */
|
||||
SRP_gN_cache *newgN = SRP_gN_new_init(ch);
|
||||
if (newgN)
|
||||
{
|
||||
if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0)
|
||||
return newgN->bn;
|
||||
SRP_gN_free(newgN);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* this function parses verifier file. Format is:
|
||||
* string(index):base64(N):base64(g):0
|
||||
* string(username):base64(v):base64(salt):int(index)
|
||||
*/
|
||||
|
||||
|
||||
int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
|
||||
{
|
||||
int error_code ;
|
||||
STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
|
||||
char *last_index = NULL;
|
||||
int i;
|
||||
char **pp;
|
||||
|
||||
SRP_gN *gN = NULL;
|
||||
SRP_user_pwd *user_pwd = NULL ;
|
||||
|
||||
TXT_DB *tmpdb = NULL;
|
||||
BIO *in = BIO_new(BIO_s_file());
|
||||
|
||||
error_code = SRP_ERR_OPEN_FILE;
|
||||
|
||||
if (in == NULL || BIO_read_filename(in,verifier_file) <= 0)
|
||||
goto err;
|
||||
|
||||
error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
|
||||
|
||||
if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL)
|
||||
goto err;
|
||||
|
||||
error_code = SRP_ERR_MEMORY;
|
||||
|
||||
|
||||
if (vb->seed_key)
|
||||
{
|
||||
last_index = SRP_get_default_gN(NULL)->id;
|
||||
}
|
||||
for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
|
||||
{
|
||||
pp = (char **)sk_OPENSSL_PSTRING_value(tmpdb->data,i);
|
||||
if (pp[DB_srptype][0] == DB_SRP_INDEX)
|
||||
{
|
||||
/*we add this couple in the internal Stack */
|
||||
|
||||
if ((gN = (SRP_gN *)OPENSSL_malloc(sizeof(SRP_gN))) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!(gN->id = BUF_strdup(pp[DB_srpid]))
|
||||
|| !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier]))
|
||||
|| !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt]))
|
||||
|| sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0)
|
||||
goto err;
|
||||
|
||||
gN = NULL;
|
||||
|
||||
if (vb->seed_key != NULL)
|
||||
{
|
||||
last_index = pp[DB_srpid];
|
||||
}
|
||||
}
|
||||
else if (pp[DB_srptype][0] == DB_SRP_VALID)
|
||||
{
|
||||
/* it is a user .... */
|
||||
SRP_gN *lgN;
|
||||
if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL)
|
||||
{
|
||||
error_code = SRP_ERR_MEMORY;
|
||||
if ((user_pwd = SRP_user_pwd_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
SRP_user_pwd_set_gN(user_pwd,lgN->g,lgN->N);
|
||||
if (!SRP_user_pwd_set_ids(user_pwd, pp[DB_srpid],pp[DB_srpinfo]))
|
||||
goto err;
|
||||
|
||||
error_code = SRP_ERR_VBASE_BN_LIB;
|
||||
if (!SRP_user_pwd_set_sv(user_pwd, pp[DB_srpsalt],pp[DB_srpverifier]))
|
||||
goto err;
|
||||
|
||||
if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
|
||||
goto err;
|
||||
user_pwd = NULL; /* abandon responsability */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last_index != NULL)
|
||||
{
|
||||
/* this means that we want to simulate a default user */
|
||||
|
||||
if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL))
|
||||
{
|
||||
error_code = SRP_ERR_VBASE_BN_LIB;
|
||||
goto err;
|
||||
}
|
||||
vb->default_g = gN->g ;
|
||||
vb->default_N = gN->N ;
|
||||
gN = NULL ;
|
||||
}
|
||||
error_code = SRP_NO_ERROR;
|
||||
|
||||
err:
|
||||
/* there may be still some leaks to fix, if this fails, the application terminates most likely */
|
||||
|
||||
if (gN != NULL)
|
||||
{
|
||||
OPENSSL_free(gN->id);
|
||||
OPENSSL_free(gN);
|
||||
}
|
||||
|
||||
SRP_user_pwd_free(user_pwd);
|
||||
|
||||
if (tmpdb) TXT_DB_free(tmpdb);
|
||||
if (in) BIO_free_all(in);
|
||||
|
||||
sk_SRP_gN_free(SRP_gN_tab);
|
||||
|
||||
return error_code;
|
||||
|
||||
}
|
||||
|
||||
|
||||
SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
|
||||
{
|
||||
int i;
|
||||
SRP_user_pwd *user;
|
||||
unsigned char digv[SHA_DIGEST_LENGTH];
|
||||
unsigned char digs[SHA_DIGEST_LENGTH];
|
||||
EVP_MD_CTX ctxt;
|
||||
|
||||
if (vb == NULL)
|
||||
return NULL;
|
||||
for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
|
||||
{
|
||||
user = sk_SRP_user_pwd_value(vb->users_pwd, i);
|
||||
if (strcmp(user->id,username)==0)
|
||||
return user;
|
||||
}
|
||||
if ((vb->seed_key == NULL) ||
|
||||
(vb->default_g == NULL) ||
|
||||
(vb->default_N == NULL))
|
||||
return NULL;
|
||||
|
||||
/* if the user is unknown we set parameters as well if we have a seed_key */
|
||||
|
||||
if ((user = SRP_user_pwd_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N);
|
||||
|
||||
if (!SRP_user_pwd_set_ids(user,username,NULL))
|
||||
goto err;
|
||||
|
||||
RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH);
|
||||
EVP_MD_CTX_init(&ctxt);
|
||||
EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
|
||||
EVP_DigestUpdate(&ctxt, username, strlen(username));
|
||||
EVP_DigestFinal_ex(&ctxt, digs, NULL);
|
||||
EVP_MD_CTX_cleanup(&ctxt);
|
||||
if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL)))
|
||||
return user;
|
||||
|
||||
err: SRP_user_pwd_free(user);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
create a verifier (*salt,*verifier,g and N are in base64)
|
||||
*/
|
||||
char *SRP_create_verifier(const char *user, const char *pass, char **salt,
|
||||
char **verifier, const char *N, const char *g)
|
||||
{
|
||||
int len;
|
||||
char * result=NULL;
|
||||
char *vf;
|
||||
BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
|
||||
unsigned char tmp[MAX_LEN];
|
||||
unsigned char tmp2[MAX_LEN];
|
||||
char * defgNid = NULL;
|
||||
|
||||
if ((user == NULL)||
|
||||
(pass == NULL)||
|
||||
(salt == NULL)||
|
||||
(verifier == NULL))
|
||||
goto err;
|
||||
|
||||
if (N)
|
||||
{
|
||||
if (!(len = t_fromb64(tmp, N))) goto err;
|
||||
N_bn = BN_bin2bn(tmp, len, NULL);
|
||||
if (!(len = t_fromb64(tmp, g))) goto err;
|
||||
g_bn = BN_bin2bn(tmp, len, NULL);
|
||||
defgNid = "*";
|
||||
}
|
||||
else
|
||||
{
|
||||
SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ;
|
||||
if (gN == NULL)
|
||||
goto err;
|
||||
N_bn = gN->N;
|
||||
g_bn = gN->g;
|
||||
defgNid = gN->id;
|
||||
}
|
||||
|
||||
if (*salt == NULL)
|
||||
{
|
||||
RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
|
||||
|
||||
s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(len = t_fromb64(tmp2, *salt)))
|
||||
goto err;
|
||||
s = BN_bin2bn(tmp2, len, NULL);
|
||||
}
|
||||
|
||||
|
||||
if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err;
|
||||
|
||||
BN_bn2bin(v,tmp);
|
||||
if (((vf = OPENSSL_malloc(BN_num_bytes(v)*2)) == NULL))
|
||||
goto err;
|
||||
t_tob64(vf, tmp, BN_num_bytes(v));
|
||||
|
||||
*verifier = vf;
|
||||
if (*salt == NULL)
|
||||
{
|
||||
char *tmp_salt;
|
||||
if ((tmp_salt = (char *)OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
|
||||
{
|
||||
OPENSSL_free(vf);
|
||||
goto err;
|
||||
}
|
||||
t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
|
||||
*salt = tmp_salt;
|
||||
}
|
||||
|
||||
result=defgNid;
|
||||
|
||||
err:
|
||||
if(N)
|
||||
{
|
||||
BN_free(N_bn);
|
||||
BN_free(g_bn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
create a verifier (*salt,*verifier,g and N are BIGNUMs)
|
||||
*/
|
||||
int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g)
|
||||
{
|
||||
int result=0;
|
||||
BIGNUM *x = NULL;
|
||||
BN_CTX *bn_ctx = BN_CTX_new();
|
||||
unsigned char tmp2[MAX_LEN];
|
||||
|
||||
if ((user == NULL)||
|
||||
(pass == NULL)||
|
||||
(salt == NULL)||
|
||||
(verifier == NULL)||
|
||||
(N == NULL)||
|
||||
(g == NULL)||
|
||||
(bn_ctx == NULL))
|
||||
goto err;
|
||||
|
||||
srp_bn_print(N);
|
||||
srp_bn_print(g);
|
||||
|
||||
if (*salt == NULL)
|
||||
{
|
||||
RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
|
||||
|
||||
*salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL);
|
||||
}
|
||||
|
||||
x = SRP_Calc_x(*salt,user,pass);
|
||||
|
||||
*verifier = BN_new();
|
||||
if(*verifier == NULL) goto err;
|
||||
|
||||
if (!BN_mod_exp(*verifier,g,x,N,bn_ctx))
|
||||
{
|
||||
BN_clear_free(*verifier);
|
||||
goto err;
|
||||
}
|
||||
|
||||
srp_bn_print(*verifier);
|
||||
|
||||
result=1;
|
||||
|
||||
err:
|
||||
|
||||
BN_clear_free(x);
|
||||
BN_CTX_free(bn_ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
162
crypto/srp/srptest.c
Normal file
162
crypto/srp/srptest.c
Normal file
@ -0,0 +1,162 @@
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_SRP
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("No SRP support\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/srp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
static void showbn(const char *name, const BIGNUM *bn)
|
||||
{
|
||||
fputs(name, stdout);
|
||||
fputs(" = ", stdout);
|
||||
BN_print_fp(stdout, bn);
|
||||
putc('\n', stdout);
|
||||
}
|
||||
|
||||
#define RANDOM_SIZE 32 /* use 256 bits on each side */
|
||||
|
||||
static int run_srp(const char *username, const char *client_pass, const char *server_pass)
|
||||
{
|
||||
int ret=-1;
|
||||
BIGNUM *s = NULL;
|
||||
BIGNUM *v = NULL;
|
||||
BIGNUM *a = NULL;
|
||||
BIGNUM *b = NULL;
|
||||
BIGNUM *u = NULL;
|
||||
BIGNUM *x = NULL;
|
||||
BIGNUM *Apub = NULL;
|
||||
BIGNUM *Bpub = NULL;
|
||||
BIGNUM *Kclient = NULL;
|
||||
BIGNUM *Kserver = NULL;
|
||||
unsigned char rand_tmp[RANDOM_SIZE];
|
||||
/* use builtin 1024-bit params */
|
||||
SRP_gN *GN = SRP_get_default_gN("1024");
|
||||
|
||||
if(GN == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to get SRP parameters\n");
|
||||
return -1;
|
||||
}
|
||||
/* Set up server's password entry */
|
||||
if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
|
||||
{
|
||||
fprintf(stderr, "Failed to create SRP verifier\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
showbn("N", GN->N);
|
||||
showbn("g", GN->g);
|
||||
showbn("Salt", s);
|
||||
showbn("Verifier", v);
|
||||
|
||||
/* Server random */
|
||||
RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
|
||||
b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
|
||||
/* TODO - check b != 0 */
|
||||
showbn("b", b);
|
||||
|
||||
/* Server's first message */
|
||||
Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
|
||||
showbn("B", Bpub);
|
||||
|
||||
if(!SRP_Verify_B_mod_N(Bpub, GN->N))
|
||||
{
|
||||
fprintf(stderr, "Invalid B\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Client random */
|
||||
RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
|
||||
a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
|
||||
/* TODO - check a != 0 */
|
||||
showbn("a", a);
|
||||
|
||||
/* Client's response */
|
||||
Apub = SRP_Calc_A(a, GN->N, GN->g);
|
||||
showbn("A", Apub);
|
||||
|
||||
if(!SRP_Verify_A_mod_N(Apub, GN->N))
|
||||
{
|
||||
fprintf(stderr, "Invalid A\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Both sides calculate u */
|
||||
u = SRP_Calc_u(Apub, Bpub, GN->N);
|
||||
|
||||
/* Client's key */
|
||||
x = SRP_Calc_x(s, username, client_pass);
|
||||
Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
|
||||
showbn("Client's key", Kclient);
|
||||
|
||||
/* Server's key */
|
||||
Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
|
||||
showbn("Server's key", Kserver);
|
||||
|
||||
if(BN_cmp(Kclient, Kserver) == 0)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Keys mismatch\n");
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
BN_clear_free(Kclient);
|
||||
BN_clear_free(Kserver);
|
||||
BN_clear_free(x);
|
||||
BN_free(u);
|
||||
BN_free(Apub);
|
||||
BN_clear_free(a);
|
||||
BN_free(Bpub);
|
||||
BN_clear_free(b);
|
||||
BN_free(s);
|
||||
BN_clear_free(v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
BIO *bio_err;
|
||||
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
|
||||
CRYPTO_malloc_debug_init();
|
||||
CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
|
||||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
/* "Negative" test, expect a mismatch */
|
||||
if(run_srp("alice", "password1", "password2") == 0)
|
||||
{
|
||||
fprintf(stderr, "Mismatched SRP run failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* "Positive" test, should pass */
|
||||
if(run_srp("alice", "password", "password") != 0)
|
||||
{
|
||||
fprintf(stderr, "Plain SRP run failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_thread_state(NULL);
|
||||
ERR_free_strings();
|
||||
CRYPTO_mem_leaks(bio_err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1459,6 +1459,66 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
|
||||
#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
|
||||
#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
|
||||
|
||||
#define sk_SRP_gN_new(st) SKM_sk_new(SRP_gN, (st))
|
||||
#define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
|
||||
#define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
|
||||
#define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
|
||||
#define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
|
||||
#define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
|
||||
#define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
|
||||
#define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
|
||||
#define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
|
||||
#define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
|
||||
#define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
|
||||
#define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
|
||||
#define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
|
||||
#define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
|
||||
#define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
|
||||
#define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
|
||||
#define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
|
||||
#define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
|
||||
#define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
|
||||
|
||||
#define sk_SRP_gN_cache_new(st) SKM_sk_new(SRP_gN_cache, (st))
|
||||
#define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
|
||||
#define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
|
||||
#define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
|
||||
#define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
|
||||
#define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
|
||||
#define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
|
||||
#define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
|
||||
#define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
|
||||
#define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
|
||||
#define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
|
||||
#define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
|
||||
#define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
|
||||
#define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
|
||||
#define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
|
||||
#define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
|
||||
#define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
|
||||
#define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
|
||||
#define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
|
||||
|
||||
#define sk_SRP_user_pwd_new(st) SKM_sk_new(SRP_user_pwd, (st))
|
||||
#define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
|
||||
#define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
|
||||
#define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
|
||||
#define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
|
||||
#define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
|
||||
#define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
|
||||
#define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
|
||||
#define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
|
||||
#define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
|
||||
#define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
|
||||
#define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
|
||||
#define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
|
||||
#define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
|
||||
#define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
|
||||
#define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
|
||||
#define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
|
||||
#define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
|
||||
#define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
|
||||
|
||||
#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
|
||||
#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
|
||||
#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
|
||||
|
@ -30,7 +30,7 @@ LIBSRC= \
|
||||
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
|
||||
ssl_ciph.c ssl_stat.c ssl_rsa.c \
|
||||
ssl_asn1.c ssl_txt.c ssl_algs.c \
|
||||
bio_ssl.c ssl_err.c kssl.c t1_reneg.c
|
||||
bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
|
||||
LIBOBJ= \
|
||||
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
|
||||
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
|
||||
@ -41,7 +41,7 @@ LIBOBJ= \
|
||||
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
|
||||
ssl_ciph.o ssl_stat.o ssl_rsa.o \
|
||||
ssl_asn1.o ssl_txt.o ssl_algs.o \
|
||||
bio_ssl.o ssl_err.o kssl.o t1_reneg.o
|
||||
bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
|
138
ssl/s3_clnt.c
138
ssl/s3_clnt.c
@ -277,6 +277,20 @@ int ssl3_connect(SSL *s)
|
||||
case SSL3_ST_CR_SRVR_HELLO_A:
|
||||
case SSL3_ST_CR_SRVR_HELLO_B:
|
||||
ret=ssl3_get_server_hello(s);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (ret == 0 && s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME)
|
||||
{
|
||||
if (!SRP_have_to_put_srp_username(s))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_MISSING_SRP_USERNAME);
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED);
|
||||
goto end;
|
||||
}
|
||||
s->state=SSL3_ST_CW_CLNT_HELLO_A;
|
||||
if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (ret <= 0) goto end;
|
||||
|
||||
if (s->hit)
|
||||
@ -358,6 +372,17 @@ int ssl3_connect(SSL *s)
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
ret=ssl3_get_server_done(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP)
|
||||
{
|
||||
if ((ret = SRP_Calc_A_param(s))<=0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_SRP_A_CALC);
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (s->s3->tmp.cert_req)
|
||||
s->state=SSL3_ST_CW_CERT_A;
|
||||
else
|
||||
@ -1283,6 +1308,86 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
}
|
||||
else
|
||||
#endif /* !OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (alg_k & SSL_kSRP)
|
||||
{
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
|
||||
i = (unsigned int)(p[0]);
|
||||
p++;
|
||||
param_len+=i+1;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
n-=param_len;
|
||||
|
||||
/* We must check if there is a certificate */
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_a & SSL_aRSA)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
#else
|
||||
if (0)
|
||||
;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
else if (alg_a & SSL_aDSS)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* !OPENSSL_NO_SRP */
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_k & SSL_kRSA)
|
||||
{
|
||||
@ -2552,6 +2657,39 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
EVP_PKEY_free(pub_key);
|
||||
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (alg_k & SSL_kSRP)
|
||||
{
|
||||
if (s->srp_ctx.A != NULL)
|
||||
{
|
||||
/* send off the data */
|
||||
n=BN_num_bytes(s->srp_ctx.A);
|
||||
s2n(n,p);
|
||||
BN_bn2bin(s->srp_ctx.A,p);
|
||||
n+=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (s->session->srp_username != NULL)
|
||||
OPENSSL_free(s->session->srp_username);
|
||||
s->session->srp_username = BUF_strdup(s->srp_ctx.login);
|
||||
if (s->session->srp_username == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
else if (alg_k & SSL_kPSK)
|
||||
{
|
||||
|
213
ssl/s3_lib.c
213
ssl/s3_lib.c
@ -2012,6 +2012,152 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
|
||||
},
|
||||
#endif /* OPENSSL_NO_ECDH */
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* Cipher C01A */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aNULL,
|
||||
SSL_3DES,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
168,
|
||||
168,
|
||||
},
|
||||
|
||||
/* Cipher C01B */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aRSA,
|
||||
SSL_3DES,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
168,
|
||||
168,
|
||||
},
|
||||
|
||||
/* Cipher C01C */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aDSS,
|
||||
SSL_3DES,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
168,
|
||||
168,
|
||||
},
|
||||
|
||||
/* Cipher C01D */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aNULL,
|
||||
SSL_AES128,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
|
||||
/* Cipher C01E */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aRSA,
|
||||
SSL_AES128,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
|
||||
/* Cipher C01F */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aDSS,
|
||||
SSL_AES128,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
|
||||
/* Cipher C020 */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aNULL,
|
||||
SSL_AES256,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
|
||||
/* Cipher C021 */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aRSA,
|
||||
SSL_AES256,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
|
||||
/* Cipher C022 */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aDSS,
|
||||
SSL_AES256,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
#ifdef TEMP_GOST_TLS
|
||||
/* Cipher FF00 */
|
||||
{
|
||||
@ -2128,6 +2274,9 @@ int ssl3_new(SSL *s)
|
||||
|
||||
s->s3=s3;
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_SRP_CTX_init(s);
|
||||
#endif
|
||||
s->method->ssl_clear(s);
|
||||
return(1);
|
||||
err:
|
||||
@ -2168,6 +2317,9 @@ void ssl3_free(SSL *s)
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
}
|
||||
if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_SRP_CTX_free(s);
|
||||
#endif
|
||||
OPENSSL_cleanse(s->s3,sizeof *s->s3);
|
||||
OPENSSL_free(s->s3);
|
||||
s->s3=NULL;
|
||||
@ -2232,6 +2384,13 @@ void ssl3_clear(SSL *s)
|
||||
s->version=SSL3_VERSION;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
static char * MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg)
|
||||
{
|
||||
return BUF_strdup(s->srp_ctx.info) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
{
|
||||
int ret=0;
|
||||
@ -2709,6 +2868,38 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
if (ctx->srp_ctx.login != NULL)
|
||||
OPENSSL_free(ctx->srp_ctx.login);
|
||||
ctx->srp_ctx.login = NULL;
|
||||
if (parg == NULL)
|
||||
break;
|
||||
if (strlen((char *)parg) > 254)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
|
||||
return 0;
|
||||
}
|
||||
if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=srp_password_from_info_cb;
|
||||
ctx->srp_ctx.info=parg;
|
||||
break;
|
||||
case SSL_CTRL_SET_SRP_ARG:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_cb_arg=parg;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
|
||||
ctx->srp_ctx.strength=larg;
|
||||
break;
|
||||
#endif
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
/* A Thawte special :-) */
|
||||
@ -2778,6 +2969,24 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
||||
HMAC_CTX *, int))fp;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_verify_param_callback=(int (*)(SSL *,void *))fp;
|
||||
break;
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.TLS_ext_srp_username_callback=(int (*)(SSL *,int *,void *))fp;
|
||||
break;
|
||||
case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
|
||||
break;
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback=(char *(*)(SSL *,void *))fp;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
return(0);
|
||||
@ -2878,6 +3087,10 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
mask_a = cert->mask_a;
|
||||
emask_k = cert->export_mask_k;
|
||||
emask_a = cert->export_mask_a;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
|
||||
emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
|
||||
#endif
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
/* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
|
||||
|
@ -1203,6 +1203,10 @@ start:
|
||||
SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_AD_MISSING_SRP_USERNAME
|
||||
if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
else if (alert_level == 2) /* fatal */
|
||||
{
|
||||
|
140
ssl/s3_srvr.c
140
ssl/s3_srvr.c
@ -179,6 +179,31 @@ static const SSL_METHOD *ssl3_get_server_method(int ver)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
static int SSL_check_srp_ext_ClientHello(SSL *s, int *ad)
|
||||
{
|
||||
int ret = SSL_ERROR_NONE;
|
||||
|
||||
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
||||
|
||||
if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
|
||||
(s->srp_ctx.TLS_ext_srp_username_callback != NULL))
|
||||
{
|
||||
if(s->srp_ctx.login == NULL)
|
||||
{
|
||||
/* There isn't any srp login extension !!! */
|
||||
ret = SSL3_AL_WARNING;
|
||||
*ad = SSL_AD_MISSING_SRP_USERNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SSL_srp_server_param_with_username(s,ad);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
|
||||
ssl3_accept,
|
||||
ssl_undefined_function,
|
||||
@ -191,6 +216,10 @@ int ssl3_accept(SSL *s)
|
||||
void (*cb)(const SSL *ssl,int type,int val)=NULL;
|
||||
int ret= -1;
|
||||
int new_state,state,skip=0;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
int srp_no_username=0;
|
||||
int extension_error,al;
|
||||
#endif
|
||||
|
||||
RAND_add(&Time,sizeof(Time),0);
|
||||
ERR_clear_error();
|
||||
@ -311,10 +340,34 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME:
|
||||
#endif
|
||||
|
||||
s->shutdown=0;
|
||||
ret=ssl3_get_client_hello(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
extension_error = 0;
|
||||
if ((al = SSL_check_srp_ext_ClientHello(s,&extension_error)) != SSL_ERROR_NONE)
|
||||
{
|
||||
ssl3_send_alert(s,al,extension_error);
|
||||
if (extension_error == SSL_AD_MISSING_SRP_USERNAME)
|
||||
{
|
||||
if (srp_no_username) goto end;
|
||||
ERR_clear_error();
|
||||
srp_no_username = 1;
|
||||
s->state=SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME;
|
||||
if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
|
||||
if ((ret=BIO_flush(s->wbio)) <= 0) goto end;
|
||||
s->init_num=0;
|
||||
break;
|
||||
}
|
||||
ret = -1;
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->renegotiate = 2;
|
||||
s->state=SSL3_ST_SW_SRVR_HELLO_A;
|
||||
@ -345,7 +398,7 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
/* Check if it is anon DH or anon ECDH, */
|
||||
/* normal PSK or KRB5 */
|
||||
/* normal PSK or KRB5 or SRP */
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
|
||||
@ -409,6 +462,10 @@ int ssl3_accept(SSL *s)
|
||||
* hint if provided */
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
|| ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* SRP: send ServerKeyExchange */
|
||||
|| (alg_k & SSL_kSRP)
|
||||
#endif
|
||||
|| (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
|
||||
|| (alg_k & SSL_kEECDH)
|
||||
@ -803,7 +860,11 @@ int ssl3_get_client_hello(SSL *s)
|
||||
* If we are SSLv3, we will respond with SSLv3, even if prompted with
|
||||
* TLSv1.
|
||||
*/
|
||||
if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
|
||||
if (s->state == SSL3_ST_SR_CLNT_HELLO_A
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|| (s->state == SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
s->state=SSL3_ST_SR_CLNT_HELLO_B;
|
||||
}
|
||||
@ -1668,14 +1729,37 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
}
|
||||
else
|
||||
#endif /* !OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (type & SSL_kSRP)
|
||||
{
|
||||
if ((s->srp_ctx.N == NULL) ||
|
||||
(s->srp_ctx.g == NULL) ||
|
||||
(s->srp_ctx.s == NULL) ||
|
||||
(s->srp_ctx.B == NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM);
|
||||
goto err;
|
||||
}
|
||||
r[0]=s->srp_ctx.N;
|
||||
r[1]=s->srp_ctx.g;
|
||||
r[2]=s->srp_ctx.s;
|
||||
r[3]=s->srp_ctx.B;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
|
||||
goto f_err;
|
||||
}
|
||||
for (i=0; r[i] != NULL; i++)
|
||||
for (i=0; r[i] != NULL && i<4; i++)
|
||||
{
|
||||
nr[i]=BN_num_bytes(r[i]);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if ((i == 2) && (type & SSL_kSRP))
|
||||
n+=1+nr[i];
|
||||
else
|
||||
#endif
|
||||
n+=2+nr[i];
|
||||
}
|
||||
|
||||
@ -1704,8 +1788,16 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
d=(unsigned char *)s->init_buf->data;
|
||||
p= &(d[4]);
|
||||
|
||||
for (i=0; r[i] != NULL; i++)
|
||||
for (i=0; r[i] != NULL && i<4; i++)
|
||||
{
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if ((i == 2) && (type & SSL_kSRP))
|
||||
{
|
||||
*p = nr[i];
|
||||
p++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
s2n(nr[i],p);
|
||||
BN_bn2bin(r[i],p);
|
||||
p+=nr[i];
|
||||
@ -2581,6 +2673,44 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (alg_k & SSL_kSRP)
|
||||
{
|
||||
int param_len;
|
||||
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (s->session->srp_username != NULL)
|
||||
OPENSSL_free(s->session->srp_username);
|
||||
s->session->srp_username = BUF_strdup(s->srp_ctx.login);
|
||||
if (s->session->srp_username == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
p+=i;
|
||||
}
|
||||
else
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
if (alg_k & SSL_kGOST)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -2664,7 +2794,7 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
return(1);
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
|
||||
err:
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
|
96
ssl/ssl.h
96
ssl/ssl.h
@ -252,6 +252,7 @@ extern "C" {
|
||||
#define SSL_TXT_kEECDH "kEECDH"
|
||||
#define SSL_TXT_kPSK "kPSK"
|
||||
#define SSL_TXT_kGOST "kGOST"
|
||||
#define SSL_TXT_kSRP "kSRP"
|
||||
|
||||
#define SSL_TXT_aRSA "aRSA"
|
||||
#define SSL_TXT_aDSS "aDSS"
|
||||
@ -275,6 +276,7 @@ extern "C" {
|
||||
#define SSL_TXT_ECDSA "ECDSA"
|
||||
#define SSL_TXT_KRB5 "KRB5"
|
||||
#define SSL_TXT_PSK "PSK"
|
||||
#define SSL_TXT_SRP "SRP"
|
||||
|
||||
#define SSL_TXT_DES "DES"
|
||||
#define SSL_TXT_3DES "3DES"
|
||||
@ -437,6 +439,7 @@ typedef struct ssl_method_st
|
||||
* ECPointFormatList [ 7 ] OCTET STRING, -- optional EC point format list from TLS extension
|
||||
* PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
|
||||
* PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity
|
||||
* SRP_username [ 11 ] EXPLICIT OCTET STRING -- optional SRP username
|
||||
* }
|
||||
* Look in ssl/ssl_asn1.c for more details
|
||||
* I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
|
||||
@ -512,6 +515,9 @@ typedef struct ssl_session_st
|
||||
unsigned char *tlsext_tick; /* Session ticket */
|
||||
size_t tlsext_ticklen; /* Session ticket length */
|
||||
long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
char *srp_username;
|
||||
#endif
|
||||
} SSL_SESSION;
|
||||
|
||||
@ -644,7 +650,42 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
|
||||
#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
|
||||
#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|
||||
typedef struct srp_ctx_st
|
||||
{
|
||||
/* param for all the callbacks */
|
||||
void *SRP_cb_arg;
|
||||
/* set client Hello login callback */
|
||||
int (*TLS_ext_srp_username_callback)(SSL *, int *, void *);
|
||||
/* set SRP N/g param callback for verification */
|
||||
int (*SRP_verify_param_callback)(SSL *, void *);
|
||||
/* set SRP client passwd callback */
|
||||
char *(*SRP_give_srp_client_pwd_callback)(SSL *, void *);
|
||||
/* set SRP client username callback */
|
||||
char *(*SRP_TLS_ext_missing_srp_client_username_callback)(SSL *, void *);
|
||||
|
||||
char *login;
|
||||
BIGNUM *N,*g,*s,*B,*A;
|
||||
BIGNUM *a,*b,*v;
|
||||
char *info;
|
||||
int strength;
|
||||
|
||||
unsigned long srp_Mask;
|
||||
} SRP_CTX;
|
||||
|
||||
/* see tls_srp.c */
|
||||
int SSL_SRP_CTX_init(SSL *s);
|
||||
int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
|
||||
int SSL_SRP_CTX_free(SSL *ctx);
|
||||
int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
|
||||
int SSL_srp_server_param_with_username(SSL *s, int *ad);
|
||||
int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key);
|
||||
int SRP_Calc_A_param(SSL *s);
|
||||
int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key);
|
||||
int SRP_have_to_put_srp_username(SSL *s);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
|
||||
#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
|
||||
@ -868,6 +909,9 @@ struct ssl_ctx_st
|
||||
unsigned int freelist_max_len;
|
||||
struct ssl3_buf_freelist_st *wbuf_freelist;
|
||||
struct ssl3_buf_freelist_st *rbuf_freelist;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SRP_CTX srp_ctx; /* ctx for SRP authentication */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1112,6 +1156,10 @@ struct ssl_st
|
||||
unsigned char *psk, unsigned int max_psk_len);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SRP_CTX srp_ctx; /* ctx for SRP authentication */
|
||||
#endif
|
||||
|
||||
SSL_CTX *ctx;
|
||||
/* set this flag to 1 and a sleep(1) is put into all SSL_read()
|
||||
* and SSL_write() calls, good for nbio debuging :-) */
|
||||
@ -1329,6 +1377,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
|
||||
#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
|
||||
#define SSL_AD_UNKNOWN_SRP_USERNAME TLS1_AD_UNKNOWN_SRP_USERNAME
|
||||
#define SSL_AD_MISSING_SRP_USERNAME TLS1_AD_MISSING_SRP_USERNAME
|
||||
|
||||
#define SSL_ERROR_NONE 0
|
||||
#define SSL_ERROR_SSL 1
|
||||
@ -1412,6 +1462,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71
|
||||
|
||||
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
|
||||
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75
|
||||
#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76
|
||||
#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB 78
|
||||
#define SSL_CTRL_SET_SRP_ARG 79
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 80
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 81
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 82
|
||||
#endif
|
||||
|
||||
#define DTLS_CTRL_GET_TIMEOUT 73
|
||||
@ -1616,6 +1675,32 @@ int SSL_set_trust(SSL *s, int trust);
|
||||
int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
|
||||
int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name);
|
||||
int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password);
|
||||
int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
|
||||
int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
|
||||
char *(*cb)(SSL *,void *));
|
||||
int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
|
||||
int (*cb)(SSL *,void *));
|
||||
int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
|
||||
int (*cb)(SSL *,int *,void *));
|
||||
int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
|
||||
char *(*cb)(SSL *,void *));
|
||||
int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
|
||||
|
||||
int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
|
||||
BIGNUM *sa, BIGNUM *v, char *info);
|
||||
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
|
||||
const char *grp);
|
||||
|
||||
BIGNUM *SSL_get_srp_g(SSL *s);
|
||||
BIGNUM *SSL_get_srp_N(SSL *s);
|
||||
|
||||
char *SSL_get_srp_username(SSL *s);
|
||||
char *SSL_get_srp_userinfo(SSL *s);
|
||||
#endif
|
||||
|
||||
void SSL_free(SSL *ssl);
|
||||
int SSL_accept(SSL *ssl);
|
||||
int SSL_connect(SSL *ssl);
|
||||
@ -2008,6 +2093,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_SET_TRUST 228
|
||||
#define SSL_F_SSL_SET_WFD 196
|
||||
#define SSL_F_SSL_SHUTDOWN 224
|
||||
#define SSL_F_SSL_SRP_CTX_INIT 293
|
||||
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
|
||||
#define SSL_F_SSL_UNDEFINED_FUNCTION 197
|
||||
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
|
||||
@ -2066,6 +2152,11 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_BAD_RSA_MODULUS_LENGTH 121
|
||||
#define SSL_R_BAD_RSA_SIGNATURE 122
|
||||
#define SSL_R_BAD_SIGNATURE 123
|
||||
#define SSL_R_BAD_SRP_A_LENGTH 2096
|
||||
#define SSL_R_BAD_SRP_B_LENGTH 2097
|
||||
#define SSL_R_BAD_SRP_G_LENGTH 2098
|
||||
#define SSL_R_BAD_SRP_N_LENGTH 2099
|
||||
#define SSL_R_BAD_SRP_S_LENGTH 2100
|
||||
#define SSL_R_BAD_SSL_FILETYPE 124
|
||||
#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125
|
||||
#define SSL_R_BAD_STATE 126
|
||||
@ -2082,6 +2173,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137
|
||||
#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138
|
||||
#define SSL_R_CIPHER_TABLE_SRC_ERROR 139
|
||||
#define SSL_R_CLIENTHELLO_SRP_TLS_EXT 2101
|
||||
#define SSL_R_CLIENTHELLO_TLSEXT 226
|
||||
#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140
|
||||
#define SSL_R_COMPRESSION_DISABLED 343
|
||||
@ -2118,6 +2210,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_INVALID_COMMAND 280
|
||||
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
|
||||
#define SSL_R_INVALID_PURPOSE 278
|
||||
#define SSL_R_INVALID_SRP_USERNAME 2107
|
||||
#define SSL_R_INVALID_STATUS_RESPONSE 328
|
||||
#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325
|
||||
#define SSL_R_INVALID_TRUST 279
|
||||
@ -2147,6 +2240,8 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_MISSING_RSA_CERTIFICATE 168
|
||||
#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169
|
||||
#define SSL_R_MISSING_RSA_SIGNING_CERT 170
|
||||
#define SSL_R_MISSING_SRP_PARAM 2103
|
||||
#define SSL_R_MISSING_SRP_USERNAME 2104
|
||||
#define SSL_R_MISSING_TMP_DH_KEY 171
|
||||
#define SSL_R_MISSING_TMP_ECDH_KEY 311
|
||||
#define SSL_R_MISSING_TMP_RSA_KEY 172
|
||||
@ -2219,6 +2314,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
|
||||
#define SSL_R_SHORT_READ 219
|
||||
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
|
||||
#define SSL_R_SRP_A_CALC 2105
|
||||
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221
|
||||
#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299
|
||||
#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321
|
||||
|
@ -566,6 +566,8 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
|
||||
/* a new state to remember that we have already receive a ClientHello without srp username extension */
|
||||
#define SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME (0x1E2|SSL_ST_ACCEPT)
|
||||
/* write to client */
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
|
||||
|
@ -114,6 +114,9 @@ typedef struct ssl_session_asn1_st
|
||||
ASN1_OCTET_STRING psk_identity_hint;
|
||||
ASN1_OCTET_STRING psk_identity;
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
ASN1_OCTET_STRING srp_username;
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
} SSL_SESSION_ASN1;
|
||||
|
||||
int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
@ -129,6 +132,9 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
unsigned char cbuf;
|
||||
int v11=0;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
int v12=0;
|
||||
#endif
|
||||
long l;
|
||||
SSL_SESSION_ASN1 a;
|
||||
@ -267,6 +273,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
a.psk_identity.data=(unsigned char *)(in->psk_identity);
|
||||
}
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (in->srp_username)
|
||||
{
|
||||
a.srp_username.length=strlen(in->srp_username);
|
||||
a.srp_username.type=V_ASN1_OCTET_STRING;
|
||||
a.srp_username.data=(unsigned char *)(in->srp_username);
|
||||
}
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
|
||||
M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
|
||||
@ -307,6 +321,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
if (in->psk_identity)
|
||||
M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (in->srp_username)
|
||||
M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
M_ASN1_I2D_seq_total();
|
||||
|
||||
@ -351,6 +369,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
if (in->compress_meth)
|
||||
M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (in->srp_username)
|
||||
M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
M_ASN1_I2D_finish();
|
||||
}
|
||||
|
||||
@ -588,5 +610,20 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
os.length=0;
|
||||
os.data=NULL;
|
||||
M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
|
||||
if (os.data)
|
||||
{
|
||||
ret->srp_username = BUF_strndup((char *)os.data, os.length);
|
||||
OPENSSL_free(os.data);
|
||||
os.data = NULL;
|
||||
os.length = 0;
|
||||
}
|
||||
else
|
||||
ret->srp_username=NULL;
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
|
||||
}
|
||||
|
@ -247,6 +247,7 @@ static const SSL_CIPHER cipher_aliases[]={
|
||||
{0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0},
|
||||
|
||||
{0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0},
|
||||
{0,SSL_TXT_kSRP,0, SSL_kSRP, 0,0,0,0,0,0,0,0},
|
||||
{0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0},
|
||||
|
||||
/* server authentication aliases */
|
||||
@ -273,6 +274,7 @@ static const SSL_CIPHER cipher_aliases[]={
|
||||
{0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0},
|
||||
{0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0},
|
||||
{0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0},
|
||||
{0,SSL_TXT_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0},
|
||||
|
||||
|
||||
/* symmetric encryption aliases */
|
||||
@ -660,6 +662,9 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
|
||||
#ifdef OPENSSL_NO_PSK
|
||||
*mkey |= SSL_kPSK;
|
||||
*auth |= SSL_aPSK;
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_SRP
|
||||
*mkey |= SSL_kSRP;
|
||||
#endif
|
||||
/* Check for presence of GOST 34.10 algorithms, and if they
|
||||
* do not present, disable appropriate auth and key exchange */
|
||||
@ -1511,6 +1516,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
|
||||
case SSL_kPSK:
|
||||
kx="PSK";
|
||||
break;
|
||||
case SSL_kSRP:
|
||||
kx="SRP";
|
||||
break;
|
||||
default:
|
||||
kx="unknown";
|
||||
}
|
||||
|
@ -250,6 +250,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"},
|
||||
{ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"},
|
||||
{ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"},
|
||||
{ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_INIT"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "SSL_UNDEFINED_CONST_FUNCTION"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"},
|
||||
@ -311,6 +312,11 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) ,"bad rsa signature"},
|
||||
{ERR_REASON(SSL_R_BAD_SIGNATURE) ,"bad signature"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) ,"bad srp a length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) ,"bad srp b length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) ,"bad srp g length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) ,"bad srp n length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) ,"bad srp s length"},
|
||||
{ERR_REASON(SSL_R_BAD_SSL_FILETYPE) ,"bad ssl filetype"},
|
||||
{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
|
||||
{ERR_REASON(SSL_R_BAD_STATE) ,"bad state"},
|
||||
@ -327,6 +333,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
|
||||
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
|
||||
{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
|
||||
{ERR_REASON(SSL_R_CLIENTHELLO_SRP_TLS_EXT),"error with the SRP username"},
|
||||
{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) ,"clienthello tlsext"},
|
||||
{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"},
|
||||
{ERR_REASON(SSL_R_COMPRESSION_DISABLED) ,"compression disabled"},
|
||||
@ -363,6 +370,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
|
||||
{ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
|
||||
{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"},
|
||||
{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
|
||||
{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
|
||||
{ERR_REASON(SSL_R_INVALID_TRUST) ,"invalid trust"},
|
||||
@ -392,6 +400,8 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_SRP_PARAM) ,"can't find SRP server param"},
|
||||
{ERR_REASON(SSL_R_MISSING_SRP_USERNAME) ,"missing srp username"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) ,"missing tmp dh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) ,"missing tmp ecdh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"},
|
||||
@ -464,6 +474,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
|
||||
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
|
||||
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
|
||||
{ERR_REASON(SSL_R_SRP_A_CALC) ,"error with the srp params"},
|
||||
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
|
||||
{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
|
||||
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
|
||||
|
@ -1657,6 +1657,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
ret->psk_client_callback=NULL;
|
||||
ret->psk_server_callback=NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_CTX_SRP_CTX_init(ret);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BUF_FREELISTS
|
||||
ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
|
||||
ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
|
||||
@ -1789,6 +1792,9 @@ void SSL_CTX_free(SSL_CTX *a)
|
||||
if (a->psk_identity_hint)
|
||||
OPENSSL_free(a->psk_identity_hint);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_CTX_SRP_CTX_free(a);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (a->client_cert_engine)
|
||||
ENGINE_finish(a->client_cert_engine);
|
||||
|
@ -289,6 +289,7 @@
|
||||
#define SSL_kEECDH 0x00000080L /* ephemeral ECDH */
|
||||
#define SSL_kPSK 0x00000100L /* PSK */
|
||||
#define SSL_kGOST 0x00000200L /* GOST key exchange */
|
||||
#define SSL_kSRP 0x00000400L /* SRP */
|
||||
|
||||
/* Bits for algorithm_auth (server authentication) */
|
||||
#define SSL_aRSA 0x00000001L /* RSA auth */
|
||||
|
@ -217,6 +217,9 @@ SSL_SESSION *SSL_SESSION_new(void)
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
ss->psk_identity_hint=NULL;
|
||||
ss->psk_identity=NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
ss->srp_username=NULL;
|
||||
#endif
|
||||
return(ss);
|
||||
}
|
||||
@ -733,6 +736,10 @@ void SSL_SESSION_free(SSL_SESSION *ss)
|
||||
OPENSSL_free(ss->psk_identity_hint);
|
||||
if (ss->psk_identity != NULL)
|
||||
OPENSSL_free(ss->psk_identity);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (ss->srp_username != NULL)
|
||||
OPENSSL_free(ss->srp_username);
|
||||
#endif
|
||||
OPENSSL_cleanse(ss,sizeof(*ss));
|
||||
OPENSSL_free(ss);
|
||||
|
@ -210,6 +210,9 @@ case SSL3_ST_SR_KEY_EXCH_A: str="SSLv3 read client key exchange A"; break;
|
||||
case SSL3_ST_SR_KEY_EXCH_B: str="SSLv3 read client key exchange B"; break;
|
||||
case SSL3_ST_SR_CERT_VRFY_A: str="SSLv3 read certificate verify A"; break;
|
||||
case SSL3_ST_SR_CERT_VRFY_B: str="SSLv3 read certificate verify B"; break;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME: str="SSLv3 waiting for a SRP username"; break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
@ -547,6 +550,11 @@ const char *SSL_alert_desc_string_long(int value)
|
||||
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
|
||||
str="unknown PSK identity";
|
||||
break;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case TLS1_AD_MISSING_SRP_USERNAME:
|
||||
str="no srp username";
|
||||
break;
|
||||
#endif
|
||||
default: str="unknown"; break;
|
||||
}
|
||||
return(str);
|
||||
|
@ -189,6 +189,10 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
|
||||
if (BIO_puts(bp,"\n PSK identity hint: ") <= 0) goto err;
|
||||
if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (BIO_puts(bp,"\n SRP username: ") <= 0) goto err;
|
||||
if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) goto err;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (x->tlsext_tick_lifetime_hint)
|
||||
{
|
||||
|
@ -181,6 +181,9 @@
|
||||
#ifndef OPENSSL_NO_DH
|
||||
#include <openssl/dh.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include <openssl/srp.h>
|
||||
#endif
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly
|
||||
@ -246,6 +249,55 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned
|
||||
unsigned int max_psk_len);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* SRP client */
|
||||
/* This is a context that we pass to all callbacks */
|
||||
typedef struct srp_client_arg_st
|
||||
{
|
||||
char *srppassin;
|
||||
char *srplogin;
|
||||
} SRP_CLIENT_ARG;
|
||||
|
||||
#define PWD_STRLEN 1024
|
||||
|
||||
static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
|
||||
{
|
||||
SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
|
||||
return BUF_strdup((char *)srp_client_arg->srppassin);
|
||||
}
|
||||
|
||||
static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
|
||||
{
|
||||
SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
|
||||
return BUF_strdup(srp_client_arg->srplogin);
|
||||
}
|
||||
|
||||
/* SRP server */
|
||||
/* This is a context that we pass to SRP server callbacks */
|
||||
typedef struct srp_server_arg_st
|
||||
{
|
||||
char *expected_user;
|
||||
char *pass;
|
||||
} SRP_SERVER_ARG;
|
||||
|
||||
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
|
||||
{
|
||||
SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
|
||||
|
||||
if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
|
||||
{
|
||||
fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
|
||||
return SSL3_AL_FATAL;
|
||||
}
|
||||
if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
|
||||
{
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL3_AL_FATAL;
|
||||
}
|
||||
return SSL_ERROR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BIO *bio_err=NULL;
|
||||
static BIO *bio_stdout=NULL;
|
||||
|
||||
@ -289,6 +341,10 @@ static void sv_usage(void)
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
fprintf(stderr," -psk arg - PSK in hex (without 0x)\n");
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
fprintf(stderr," -srpuser user - SRP username to use\n");
|
||||
fprintf(stderr," -srppass arg - password for 'user'\n");
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
fprintf(stderr," -ssl2 - use SSLv2\n");
|
||||
#endif
|
||||
@ -475,6 +531,13 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
EC_KEY *ecdh = NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* client */
|
||||
int srp_lateuser = 0;
|
||||
SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
|
||||
/* server */
|
||||
SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
|
||||
#endif
|
||||
int no_dhe = 0;
|
||||
int no_ecdhe = 0;
|
||||
@ -572,6 +635,20 @@ int main(int argc, char *argv[])
|
||||
no_psk=1;
|
||||
#endif
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (strcmp(*argv,"-srpuser") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
|
||||
tls1=1;
|
||||
}
|
||||
else if (strcmp(*argv,"-srppass") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
|
||||
tls1=1;
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv,"-ssl2") == 0)
|
||||
ssl2=1;
|
||||
else if (strcmp(*argv,"-tls1") == 0)
|
||||
@ -940,6 +1017,28 @@ bad:
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (srp_client_arg.srplogin)
|
||||
{
|
||||
if (srp_lateuser)
|
||||
SSL_CTX_set_srp_missing_srp_username_callback(c_ctx,missing_srp_username_callback);
|
||||
else if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
|
||||
{
|
||||
BIO_printf(bio_err,"Unable to set SRP username\n");
|
||||
goto end;
|
||||
}
|
||||
SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
|
||||
SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
|
||||
/*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
|
||||
}
|
||||
|
||||
if (srp_server_arg.expected_user != NULL)
|
||||
{
|
||||
SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
|
||||
SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
|
||||
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
|
||||
}
|
||||
#endif
|
||||
|
||||
c_ssl=SSL_new(c_ctx);
|
||||
s_ssl=SSL_new(s_ctx);
|
||||
|
@ -1073,6 +1073,9 @@ int tls1_alert_code(int code)
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
|
||||
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL_AD_MISSING_SRP_USERNAME:return(TLS1_AD_MISSING_SRP_USERNAME);
|
||||
#endif
|
||||
#if 0 /* not appropriate for TLS, not used for DTLS */
|
||||
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
|
||||
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
|
||||
|
37
ssl/t1_lib.c
37
ssl/t1_lib.c
@ -341,6 +341,30 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
ret += el;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
/* we add SRP username the first time only if we have one! */
|
||||
if (s->srp_ctx.login != NULL)
|
||||
{/* Add TLS extension SRP username to the Client Hello message */
|
||||
int login_len = MIN(strlen(s->srp_ctx.login) + 1, 255);
|
||||
long lenmax;
|
||||
|
||||
if ((lenmax = limit - ret - 5) < 0) return NULL;
|
||||
if (login_len > lenmax) return NULL;
|
||||
if (login_len > 255)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
s2n(TLSEXT_TYPE_srp,ret);
|
||||
s2n(login_len+1,ret);
|
||||
|
||||
(*ret++) = (unsigned char) MIN(strlen(s->srp_ctx.login), 254);
|
||||
memcpy(ret, s->srp_ctx.login, MIN(strlen(s->srp_ctx.login), 254));
|
||||
ret+=login_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (s->tlsext_ecpointformatlist != NULL &&
|
||||
s->version != DTLS1_VERSION)
|
||||
@ -762,6 +786,19 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
||||
}
|
||||
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (type == TLSEXT_TYPE_srp)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
len = data[0];
|
||||
if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL)
|
||||
return -1;
|
||||
memcpy(s->srp_ctx.login, &data[1], len);
|
||||
s->srp_ctx.login[len]='\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
else if (type == TLSEXT_TYPE_ec_point_formats &&
|
||||
|
26
ssl/tls1.h
26
ssl/tls1.h
@ -186,6 +186,8 @@ extern "C" {
|
||||
#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
|
||||
#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
|
||||
#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */
|
||||
#define TLS1_AD_UNKNOWN_SRP_USERNAME 120 /* fatal */
|
||||
#define TLS1_AD_MISSING_SRP_USERNAME 121
|
||||
|
||||
/* ExtensionType values from RFC3546 / RFC4366 */
|
||||
#define TLSEXT_TYPE_server_name 0
|
||||
@ -197,6 +199,8 @@ extern "C" {
|
||||
/* ExtensionType values from RFC4492 */
|
||||
#define TLSEXT_TYPE_elliptic_curves 10
|
||||
#define TLSEXT_TYPE_ec_point_formats 11
|
||||
/* ExtensionType value from RFC5054 */
|
||||
#define TLSEXT_TYPE_srp 12
|
||||
#define TLSEXT_TYPE_session_ticket 35
|
||||
/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
|
||||
#if 0 /* will have to be provided externally for now ,
|
||||
@ -380,6 +384,17 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
|
||||
#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018
|
||||
#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019
|
||||
|
||||
/* SRP ciphersuites from RFC 5054 */
|
||||
#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A
|
||||
#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B
|
||||
#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C
|
||||
#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D
|
||||
#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E
|
||||
#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F
|
||||
#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020
|
||||
#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021
|
||||
#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022
|
||||
|
||||
/* XXX
|
||||
* Inconsistency alert:
|
||||
* The OpenSSL names of ciphers with ephemeral DH here include the string
|
||||
@ -447,6 +462,17 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
|
||||
#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA"
|
||||
#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA"
|
||||
|
||||
/* SRP ciphersuite from RFC 5054 */
|
||||
#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA"
|
||||
|
||||
/* Camellia ciphersuites from RFC4132 */
|
||||
#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA"
|
||||
#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA"
|
||||
|
527
ssl/tls_srp.c
Normal file
527
ssl/tls_srp.c
Normal file
@ -0,0 +1,527 @@
|
||||
/* ssl/tls_srp.c */
|
||||
/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
|
||||
* the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include "ssl_locl.h"
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/srp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
OPENSSL_free(ctx->srp_ctx.login);
|
||||
BN_free(ctx->srp_ctx.N);
|
||||
BN_free(ctx->srp_ctx.g);
|
||||
BN_free(ctx->srp_ctx.s);
|
||||
BN_free(ctx->srp_ctx.B);
|
||||
BN_free(ctx->srp_ctx.A);
|
||||
BN_free(ctx->srp_ctx.a);
|
||||
BN_free(ctx->srp_ctx.b);
|
||||
BN_free(ctx->srp_ctx.v);
|
||||
ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
|
||||
ctx->srp_ctx.SRP_cb_arg = NULL;
|
||||
ctx->srp_ctx.SRP_verify_param_callback = NULL;
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
|
||||
ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
|
||||
ctx->srp_ctx.N = NULL;
|
||||
ctx->srp_ctx.g = NULL;
|
||||
ctx->srp_ctx.s = NULL;
|
||||
ctx->srp_ctx.B = NULL;
|
||||
ctx->srp_ctx.A = NULL;
|
||||
ctx->srp_ctx.a = NULL;
|
||||
ctx->srp_ctx.b = NULL;
|
||||
ctx->srp_ctx.v = NULL;
|
||||
ctx->srp_ctx.login = NULL;
|
||||
ctx->srp_ctx.info = NULL;
|
||||
ctx->srp_ctx.strength = SRP_MINIMAL_N;
|
||||
ctx->srp_ctx.srp_Mask = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int SSL_SRP_CTX_free(struct ssl_st *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
OPENSSL_free(s->srp_ctx.login);
|
||||
BN_free(s->srp_ctx.N);
|
||||
BN_free(s->srp_ctx.g);
|
||||
BN_free(s->srp_ctx.s);
|
||||
BN_free(s->srp_ctx.B);
|
||||
BN_free(s->srp_ctx.A);
|
||||
BN_free(s->srp_ctx.a);
|
||||
BN_free(s->srp_ctx.b);
|
||||
BN_free(s->srp_ctx.v);
|
||||
s->srp_ctx.TLS_ext_srp_username_callback = NULL;
|
||||
s->srp_ctx.SRP_cb_arg = NULL;
|
||||
s->srp_ctx.SRP_verify_param_callback = NULL;
|
||||
s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
|
||||
s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
|
||||
s->srp_ctx.N = NULL;
|
||||
s->srp_ctx.g = NULL;
|
||||
s->srp_ctx.s = NULL;
|
||||
s->srp_ctx.B = NULL;
|
||||
s->srp_ctx.A = NULL;
|
||||
s->srp_ctx.a = NULL;
|
||||
s->srp_ctx.b = NULL;
|
||||
s->srp_ctx.v = NULL;
|
||||
s->srp_ctx.login = NULL;
|
||||
s->srp_ctx.info = NULL;
|
||||
s->srp_ctx.strength = SRP_MINIMAL_N;
|
||||
s->srp_ctx.srp_Mask = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int SSL_SRP_CTX_init(struct ssl_st *s)
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
|
||||
if ((s == NULL) || ((ctx = s->ctx) == NULL))
|
||||
return 0;
|
||||
s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
|
||||
/* set client Hello login callback */
|
||||
s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
|
||||
/* set SRP N/g param callback for verification */
|
||||
s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
|
||||
/* set SRP client passwd callback */
|
||||
s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
|
||||
s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback;
|
||||
|
||||
s->srp_ctx.N = NULL;
|
||||
s->srp_ctx.g = NULL;
|
||||
s->srp_ctx.s = NULL;
|
||||
s->srp_ctx.B = NULL;
|
||||
s->srp_ctx.A = NULL;
|
||||
s->srp_ctx.a = NULL;
|
||||
s->srp_ctx.b = NULL;
|
||||
s->srp_ctx.v = NULL;
|
||||
s->srp_ctx.login = NULL;
|
||||
s->srp_ctx.info = ctx->srp_ctx.info;
|
||||
s->srp_ctx.strength = ctx->srp_ctx.strength;
|
||||
|
||||
if (((ctx->srp_ctx.N != NULL) &&
|
||||
((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
|
||||
((ctx->srp_ctx.g != NULL) &&
|
||||
((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
|
||||
((ctx->srp_ctx.s != NULL) &&
|
||||
((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
|
||||
((ctx->srp_ctx.B != NULL) &&
|
||||
((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
|
||||
((ctx->srp_ctx.A != NULL) &&
|
||||
((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
|
||||
((ctx->srp_ctx.a != NULL) &&
|
||||
((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
|
||||
((ctx->srp_ctx.v != NULL) &&
|
||||
((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
|
||||
((ctx->srp_ctx.b != NULL) &&
|
||||
((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if ((ctx->srp_ctx.login != NULL) &&
|
||||
((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
|
||||
|
||||
return (1);
|
||||
err:
|
||||
OPENSSL_free(s->srp_ctx.login);
|
||||
BN_free(s->srp_ctx.N);
|
||||
BN_free(s->srp_ctx.g);
|
||||
BN_free(s->srp_ctx.s);
|
||||
BN_free(s->srp_ctx.B);
|
||||
BN_free(s->srp_ctx.A);
|
||||
BN_free(s->srp_ctx.a);
|
||||
BN_free(s->srp_ctx.b);
|
||||
BN_free(s->srp_ctx.v);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
ctx->srp_ctx.SRP_cb_arg = NULL;
|
||||
/* set client Hello login callback */
|
||||
ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
|
||||
/* set SRP N/g param callback for verification */
|
||||
ctx->srp_ctx.SRP_verify_param_callback = NULL;
|
||||
/* set SRP client passwd callback */
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
|
||||
ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
|
||||
|
||||
ctx->srp_ctx.N = NULL;
|
||||
ctx->srp_ctx.g = NULL;
|
||||
ctx->srp_ctx.s = NULL;
|
||||
ctx->srp_ctx.B = NULL;
|
||||
ctx->srp_ctx.A = NULL;
|
||||
ctx->srp_ctx.a = NULL;
|
||||
ctx->srp_ctx.b = NULL;
|
||||
ctx->srp_ctx.v = NULL;
|
||||
ctx->srp_ctx.login = NULL;
|
||||
ctx->srp_ctx.srp_Mask = 0;
|
||||
ctx->srp_ctx.info = NULL;
|
||||
ctx->srp_ctx.strength = SRP_MINIMAL_N;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* server side */
|
||||
int SSL_srp_server_param_with_username(SSL *s, int *ad)
|
||||
{
|
||||
unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
int al;
|
||||
|
||||
*ad = SSL_AD_UNKNOWN_SRP_USERNAME;
|
||||
if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
|
||||
((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
|
||||
return al;
|
||||
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
if ((s->srp_ctx.N == NULL) ||
|
||||
(s->srp_ctx.g == NULL) ||
|
||||
(s->srp_ctx.s == NULL) ||
|
||||
(s->srp_ctx.v == NULL))
|
||||
return SSL3_AL_FATAL;
|
||||
|
||||
RAND_bytes(b, sizeof(b));
|
||||
s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
|
||||
OPENSSL_cleanse(b,sizeof(b));
|
||||
|
||||
/* Calculate: B = (kv + g^b) % N */
|
||||
|
||||
return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
|
||||
SSL_ERROR_NONE:SSL3_AL_FATAL;
|
||||
}
|
||||
|
||||
/* If the server just has the raw password, make up a verifier entry on the fly */
|
||||
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
|
||||
{
|
||||
SRP_gN *GN = SRP_get_default_gN(grp);
|
||||
if(GN == NULL) return -1;
|
||||
s->srp_ctx.N = BN_dup(GN->N);
|
||||
s->srp_ctx.g = BN_dup(GN->g);
|
||||
if(s->srp_ctx.v != NULL)
|
||||
{
|
||||
BN_clear_free(s->srp_ctx.v);
|
||||
s->srp_ctx.v = NULL;
|
||||
}
|
||||
if(s->srp_ctx.s != NULL)
|
||||
{
|
||||
BN_clear_free(s->srp_ctx.s);
|
||||
s->srp_ctx.s = NULL;
|
||||
}
|
||||
if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
|
||||
BIGNUM *sa, BIGNUM *v, char *info)
|
||||
{
|
||||
if (N!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.N != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.N,N))
|
||||
{
|
||||
BN_free(s->srp_ctx.N);
|
||||
s->srp_ctx.N = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.N = BN_dup(N);
|
||||
}
|
||||
if (g!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.g != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.g,g))
|
||||
{
|
||||
BN_free(s->srp_ctx.g);
|
||||
s->srp_ctx.g = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.g = BN_dup(g);
|
||||
}
|
||||
if (sa!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.s != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.s,sa))
|
||||
{
|
||||
BN_free(s->srp_ctx.s);
|
||||
s->srp_ctx.s = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.s = BN_dup(sa);
|
||||
}
|
||||
if (v!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.v != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.v,v))
|
||||
{
|
||||
BN_free(s->srp_ctx.v);
|
||||
s->srp_ctx.v = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.v = BN_dup(v);
|
||||
}
|
||||
s->srp_ctx.info = info;
|
||||
|
||||
if (!(s->srp_ctx.N) ||
|
||||
!(s->srp_ctx.g) ||
|
||||
!(s->srp_ctx.s) ||
|
||||
!(s->srp_ctx.v))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
|
||||
{
|
||||
BIGNUM *K = NULL, *u = NULL;
|
||||
int ret = -1, tmp_len;
|
||||
unsigned char *tmp = NULL;
|
||||
|
||||
if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
|
||||
goto err;
|
||||
if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
|
||||
goto err;
|
||||
if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
|
||||
goto err;
|
||||
|
||||
tmp_len = BN_num_bytes(K);
|
||||
if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
|
||||
goto err;
|
||||
BN_bn2bin(K, tmp);
|
||||
ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
|
||||
err:
|
||||
if (tmp)
|
||||
{
|
||||
OPENSSL_cleanse(tmp,tmp_len) ;
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
BN_clear_free(K);
|
||||
BN_clear_free(u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* client side */
|
||||
int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
|
||||
{
|
||||
BIGNUM *x = NULL, *u = NULL, *K = NULL;
|
||||
int ret = -1, tmp_len;
|
||||
char *passwd = NULL;
|
||||
unsigned char *tmp = NULL;
|
||||
|
||||
/* Checks if b % n == 0
|
||||
*/
|
||||
if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
|
||||
if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
|
||||
if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
|
||||
if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
|
||||
if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
|
||||
if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;
|
||||
|
||||
tmp_len = BN_num_bytes(K);
|
||||
if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
|
||||
BN_bn2bin(K, tmp);
|
||||
ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
|
||||
err:
|
||||
if (tmp)
|
||||
{
|
||||
OPENSSL_cleanse(tmp,tmp_len) ;
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
BN_clear_free(K);
|
||||
BN_clear_free(x);
|
||||
if (passwd)
|
||||
{
|
||||
OPENSSL_cleanse(passwd,strlen(passwd)) ;
|
||||
OPENSSL_free(passwd);
|
||||
}
|
||||
BN_clear_free(u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SRP_Calc_A_param(SSL *s)
|
||||
{
|
||||
unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
|
||||
if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
|
||||
return -1;
|
||||
|
||||
if (s->srp_ctx.SRP_verify_param_callback ==NULL &&
|
||||
!SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
|
||||
return -1 ;
|
||||
|
||||
RAND_bytes(rnd, sizeof(rnd));
|
||||
s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
|
||||
OPENSSL_cleanse(rnd, sizeof(rnd));
|
||||
|
||||
if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
|
||||
return -1;
|
||||
|
||||
/* We can have a callback to verify SRP param!! */
|
||||
if (s->srp_ctx.SRP_verify_param_callback !=NULL)
|
||||
return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SRP_have_to_put_srp_username(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback == NULL)
|
||||
return 0;
|
||||
if ((s->srp_ctx.login = s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback(s,s->srp_ctx.SRP_cb_arg)) == NULL)
|
||||
return 0;
|
||||
s->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIGNUM *SSL_get_srp_g(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.g != NULL)
|
||||
return s->srp_ctx.g;
|
||||
return s->ctx->srp_ctx.g;
|
||||
}
|
||||
|
||||
BIGNUM *SSL_get_srp_N(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.N != NULL)
|
||||
return s->srp_ctx.N;
|
||||
return s->ctx->srp_ctx.N;
|
||||
}
|
||||
|
||||
char *SSL_get_srp_username(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.login != NULL)
|
||||
return s->srp_ctx.login;
|
||||
return s->ctx->srp_ctx.login;
|
||||
}
|
||||
|
||||
char *SSL_get_srp_userinfo(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.info != NULL)
|
||||
return s->srp_ctx.info;
|
||||
return s->ctx->srp_ctx.info;
|
||||
}
|
||||
|
||||
#define tls1_ctx_ctrl ssl3_ctx_ctrl
|
||||
#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
|
||||
|
||||
int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
|
||||
int (*cb)(SSL *,int *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
|
||||
char *(*cb)(SSL *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx,
|
||||
SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
#endif
|
@ -61,6 +61,7 @@ ENGINETEST= enginetest
|
||||
EVPTEST= evp_test
|
||||
IGETEST= igetest
|
||||
JPAKETEST= jpaketest
|
||||
SRPTEST= srptest
|
||||
ASN1TEST= asn1test
|
||||
|
||||
TESTS= alltests
|
||||
@ -72,7 +73,7 @@ EXE= $(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_EXT) $(ECDSATEST)$(EXE_EXT) $(ECDHTEST)
|
||||
$(MDC2TEST)$(EXE_EXT) $(RMDTEST)$(EXE_EXT) \
|
||||
$(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \
|
||||
$(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
|
||||
$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) \
|
||||
$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT) \
|
||||
$(ASN1TEST)$(EXE_EXT)
|
||||
|
||||
# $(METHTEST)$(EXE_EXT)
|
||||
@ -93,7 +94,7 @@ SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
|
||||
$(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \
|
||||
$(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
|
||||
$(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c \
|
||||
$(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(ASN1TEST).c
|
||||
$(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c
|
||||
|
||||
EXHEADER=
|
||||
HEADER= $(EXHEADER)
|
||||
@ -136,7 +137,7 @@ alltests: \
|
||||
test_enc test_x509 test_rsa test_crl test_sid \
|
||||
test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
|
||||
test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \
|
||||
test_jpake test_cms
|
||||
test_jpake test_srp test_cms
|
||||
|
||||
test_evp:
|
||||
../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
|
||||
@ -310,6 +311,10 @@ test_cms:
|
||||
@echo "CMS consistency test"
|
||||
$(PERL) cms-test.pl
|
||||
|
||||
test_srp: $(SRPTEST)$(EXE_EXT)
|
||||
@echo "Test SRP"
|
||||
../util/shlib_wrap.sh ./srptest
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
@ -446,6 +451,9 @@ $(JPAKETEST)$(EXE_EXT): $(JPAKETEST).o $(DLIBCRYPTO)
|
||||
$(ASN1TEST)$(EXE_EXT): $(ASN1TEST).o $(DLIBCRYPTO)
|
||||
@target=$(ASN1TEST); $(BUILD_CMD)
|
||||
|
||||
$(SRPTEST)$(EXE_EXT): $(SRPTEST).o $(DLIBCRYPTO)
|
||||
@target=$(SRPTEST); $(BUILD_CMD)
|
||||
|
||||
#$(AESTEST).o: $(AESTEST).c
|
||||
# $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
|
||||
|
||||
|
10
test/testssl
10
test/testssl
@ -148,4 +148,14 @@ $ssltest -tls1 -cipher PSK -psk abc123 $extra || exit 1
|
||||
echo test tls1 with PSK via BIO pair
|
||||
$ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1
|
||||
|
||||
if ../util/shlib_wrap.sh ../apps/openssl no-srp; then
|
||||
echo skipping SRP tests
|
||||
else
|
||||
echo test tls1 with SRP
|
||||
$ssltest -tls1 -cipher SRP -srpuser test -srppass abc123
|
||||
|
||||
echo test tls1 with SRP via BIO pair
|
||||
$ssltest -bio_pair -tls1 -cipher SRP -srpuser test -srppass abc123
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
@ -4189,3 +4189,19 @@ CRYPTO_cts128_encrypt_block 4560 EXIST::FUNCTION:
|
||||
CRYPTO_cbc128_decrypt 4561 EXIST::FUNCTION:
|
||||
CRYPTO_cfb128_encrypt 4562 EXIST::FUNCTION:
|
||||
CRYPTO_cfb128_8_encrypt 4563 EXIST::FUNCTION:
|
||||
SRP_VBASE_get_by_user 4564 EXIST::FUNCTION:SRP
|
||||
SRP_Calc_server_key 4565 EXIST::FUNCTION:SRP
|
||||
SRP_create_verifier 4566 EXIST::FUNCTION:SRP
|
||||
SRP_create_verifier_BN 4567 EXIST::FUNCTION:SRP
|
||||
SRP_Calc_u 4568 EXIST::FUNCTION:SRP
|
||||
SRP_VBASE_free 4569 EXIST::FUNCTION:SRP
|
||||
SRP_Calc_client_key 4570 EXIST::FUNCTION:SRP
|
||||
SRP_get_default_gN 4571 EXIST::FUNCTION:SRP
|
||||
SRP_Calc_x 4572 EXIST::FUNCTION:SRP
|
||||
SRP_Calc_B 4573 EXIST::FUNCTION:SRP
|
||||
SRP_VBASE_new 4574 EXIST::FUNCTION:SRP
|
||||
SRP_check_known_gN_param 4575 EXIST::FUNCTION:SRP
|
||||
SRP_Calc_A 4576 EXIST::FUNCTION:SRP
|
||||
SRP_Verify_A_mod_N 4577 EXIST::FUNCTION:SRP
|
||||
SRP_VBASE_init 4578 EXIST::FUNCTION:SRP
|
||||
SRP_Verify_B_mod_N 4579 EXIST::FUNCTION:SRP
|
||||
|
@ -104,6 +104,7 @@ and [options] can be one of
|
||||
just-ssl - remove all non-ssl keys/digest
|
||||
no-asm - No x86 asm
|
||||
no-krb5 - No KRB5
|
||||
no-srp - No SRP
|
||||
no-ec - No EC
|
||||
no-ecdsa - No ECDSA
|
||||
no-ecdh - No ECDH
|
||||
@ -261,6 +262,7 @@ $cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
|
||||
$cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
|
||||
$cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
|
||||
$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
|
||||
$cflags.=" -DOPENSSL_NO_SRP" if $no_srp;
|
||||
$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
|
||||
$cflags.=" -DOPENSSL_NO_ERR" if $no_err;
|
||||
$cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
|
||||
@ -781,6 +783,8 @@ sub var_add
|
||||
@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
|
||||
@a=grep(!/_mdc2$/,@a) if $no_mdc2;
|
||||
|
||||
@a=grep(!/(srp)/,@a) if $no_srp;
|
||||
|
||||
@a=grep(!/^engine$/,@a) if $no_engine;
|
||||
@a=grep(!/^hw$/,@a) if $no_hw;
|
||||
@a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
|
||||
@ -1056,6 +1060,7 @@ sub read_options
|
||||
"no-ssl2" => \$no_ssl2,
|
||||
"no-ssl3" => \$no_ssl3,
|
||||
"no-tlsext" => \$no_tlsext,
|
||||
"no-srp" => \$no_srp,
|
||||
"no-cms" => \$no_cms,
|
||||
"no-jpake" => \$no_jpake,
|
||||
"no-err" => \$no_err,
|
||||
@ -1071,7 +1076,7 @@ sub read_options
|
||||
[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
|
||||
\$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
|
||||
\$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
|
||||
\$no_aes, \$no_camellia, \$no_seed],
|
||||
\$no_aes, \$no_camellia, \$no_seed, \$no_srp],
|
||||
"rsaref" => 0,
|
||||
"gcc" => \$gcc,
|
||||
"debug" => \$debug,
|
||||
|
@ -98,7 +98,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
|
||||
# RFC3779
|
||||
"RFC3779",
|
||||
# TLS
|
||||
"TLSEXT", "PSK",
|
||||
"TLSEXT", "PSK", "SRP",
|
||||
# CMS
|
||||
"CMS",
|
||||
# CryptoAPI Engine
|
||||
@ -127,7 +127,7 @@ my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
|
||||
my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
|
||||
my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
|
||||
my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
|
||||
my $no_jpake; my $no_ssl2;
|
||||
my $no_jpake; my $no_srp; my $no_ssl2;
|
||||
|
||||
my $zlib;
|
||||
|
||||
@ -218,6 +218,7 @@ foreach (@ARGV, split(/ /, $options))
|
||||
elsif (/^no-ssl2$/) { $no_ssl2=1; }
|
||||
elsif (/^no-capieng$/) { $no_capieng=1; }
|
||||
elsif (/^no-jpake$/) { $no_jpake=1; }
|
||||
elsif (/^no-srp$/) { $no_srp=1; }
|
||||
}
|
||||
|
||||
|
||||
@ -317,6 +318,7 @@ $crypto.=" crypto/pqueue/pqueue.h";
|
||||
$crypto.=" crypto/cms/cms.h";
|
||||
$crypto.=" crypto/jpake/jpake.h";
|
||||
$crypto.=" crypto/modes/modes.h";
|
||||
$crypto.=" crypto/srp/srp.h";
|
||||
|
||||
my $symhacks="crypto/symhacks.h";
|
||||
|
||||
@ -1173,6 +1175,7 @@ sub is_valid
|
||||
if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
|
||||
if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
|
||||
if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
|
||||
if ($keyword eq "SRP" && $no_srp) { return 0; }
|
||||
if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
|
||||
|
||||
# Nothing recognise as true
|
||||
|
@ -62,6 +62,7 @@ my @dirs = (
|
||||
"crypto/pqueue",
|
||||
"crypto/whrlpool",
|
||||
"crypto/ts",
|
||||
"crypto/srp",
|
||||
"ssl",
|
||||
"apps",
|
||||
"engines",
|
||||
|
@ -264,3 +264,17 @@ SSL_renegotiate_abbreviated 312 EXIST::FUNCTION:
|
||||
TLSv1_1_method 313 EXIST::FUNCTION:
|
||||
TLSv1_1_client_method 314 EXIST::FUNCTION:
|
||||
TLSv1_1_server_method 315 EXIST::FUNCTION:
|
||||
SSL_CTX_set_srp_client_pwd_callback 316 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_get_srp_g 317 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_username_callback 318 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_get_srp_userinfo 319 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_set_srp_server_param 320 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_set_srp_server_param_pw 321 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_get_srp_N 322 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_get_srp_username 323 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_password 324 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_strength 325 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_verify_param_callback 326 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_missing_srp_username_callback 327 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_cb_arg 328 EXIST::FUNCTION:SRP,TLSEXT
|
||||
SSL_CTX_set_srp_username 329 EXIST::FUNCTION:SRP,TLSEXT
|
||||
|
Loading…
Reference in New Issue
Block a user