+#ifndef OPENSSL_NO_SRP
+/* This is a context that we pass to callbacks */
+typedef struct srpsrvparm_st
+ {
+ char *login;
+ SRP_VBASE *vb;
+ SRP_user_pwd *user;
+ } srpsrvparm;
+
+/* This callback pretends to require some asynchronous logic in order to obtain
+ a verifier. When the callback is called for a new connection we return
+ with a negative value. This will provoke the accept etc to return with
+ an LOOKUP_X509. The main logic of the reinvokes the suspended call
+ (which would normally occur after a worker has finished) and we
+ set the user parameters.
+*/
+static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+ {
+ srpsrvparm *p = (srpsrvparm *)arg;
+ if (p->login == NULL && p->user == NULL )
+ {
+ p->login = SSL_get_srp_username(s);
+ BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
+ return (-1) ;
+ }
+
+ if (p->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, p->user->N, p->user->g, p->user->s, p->user->v,
+ p->user->info) < 0)
+ {
+ *ad = SSL_AD_INTERNAL_ERROR;
+ return SSL3_AL_FATAL;
+ }
+ BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
+ /* need to check whether there are memory leaks */
+ p->user = NULL;
+ p->login = NULL;
+ return SSL_ERROR_NONE;
+ }
+
+#endif
+