Browse code

Update cyrus-sasl memory leak fix patch

Change-Id: I949951559a1b59f55d435a7601dc136b1aa19da9
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4367
Reviewed-by: Jonathan Brown
Reviewed-by: Anish Swaminathan <anishs@vmware.com>
Tested-by: Anish Swaminathan <anishs@vmware.com>

suezzelur authored on 2017/11/22 12:26:04
Showing 2 changed files
... ...
@@ -1,1134 +1,1133 @@
1
-diff -rupN cyrus-sasl-2.1.26/plugins/srp.c cyrus-sasl-2.1.26-new/plugins/srp.c
2
-+++ cyrus-sasl-2.1.26-new/plugins/srp.c	2017-10-10 16:35:43.846721591 -0700
3
-@@ -1,10 +1,9 @@
4
- /* SRP SASL plugin
5
-  * Ken Murchison
6
-  * Tim Martin  3/17/00
7
-- * $Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $
8
-  */
9
- /* 
10
-- * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
11
-+ * Copyright (c) 1998-2016 Carnegie Mellon University.  All rights reserved.
12
-  *
13
-  * Redistribution and use in source and binary forms, with or without
14
-  * modification, are permitted provided that the following conditions
15
-@@ -22,12 +21,13 @@
16
-  *    endorse or promote products derived from this software without
17
-  *    prior written permission. For permission or any other legal
18
-  *    details, please contact  
19
-- *      Office of Technology Transfer
20
-  *      Carnegie Mellon University
21
-- *      5000 Forbes Avenue
22
-- *      Pittsburgh, PA  15213-3890
23
-- *      (412) 268-4387, fax: (412) 268-7395
24
-- *      tech-transfer@andrew.cmu.edu
25
-+ *      Center for Technology Transfer and Enterprise Creation
26
-+ *      4615 Forbes Avenue
27
-+ *      Suite 302
28
-+ *      Pittsburgh, PA  15213
29
-+ *      (412) 268-7393, fax: (412) 268-7395
30
-+ *      innovation@andrew.cmu.edu
31
-  *
32
-  * 4. Redistributions of any form whatsoever must retain the following
33
-  *    acknowledgment:
34
-@@ -101,8 +101,6 @@ typedef unsigned short uint32;
35
- 
36
- /*****************************  Common Section  *****************************/
37
- 
38
--static const char plugin_id[] = "$Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $";
39
--
40
- /* Size limit of cipher block size */
41
- #define SRP_MAXBLOCKSIZE 16
42
- /* Size limit of SRP buffer */
43
-@@ -216,22 +214,22 @@ typedef struct srp_options_s {
44
- typedef struct context {
45
-     int state;
46
-     
47
--    BIGNUM N;			/* safe prime modulus */
48
--    BIGNUM g;			/* generator */
49
-+    BIGNUM *N;			/* safe prime modulus */
50
-+    BIGNUM *g;			/* generator */
51
-     
52
--    BIGNUM v;			/* password verifier */
53
-+    BIGNUM *v;			/* password verifier */
54
-     
55
--    BIGNUM b;			/* server private key */
56
--    BIGNUM B;			/* server public key */
57
-+    BIGNUM *b;			/* server private key */
58
-+    BIGNUM *B;			/* server public key */
59
-     
60
--    BIGNUM a;			/* client private key */
61
--    BIGNUM A;			/* client public key */
62
-+    BIGNUM *a;			/* client private key */
63
-+    BIGNUM *A;			/* client public key */
64
-     
65
--    char K[EVP_MAX_MD_SIZE];	/* shared context key */
66
--    int Klen;
67
-+    unsigned char K[EVP_MAX_MD_SIZE];	/* shared context key */
68
-+    unsigned int Klen;
69
-     
70
--    char M1[EVP_MAX_MD_SIZE];	/* client evidence */
71
--    int M1len;
72
-+    unsigned char M1[EVP_MAX_MD_SIZE];	/* client evidence */
73
-+    unsigned int M1len;
74
-     
75
-     char *authid;		/* authentication id (server) */
76
-     char *userid;		/* authorization id (server) */
77
-@@ -242,7 +240,7 @@ typedef struct context {
78
-     char *server_options;
79
-     
80
-     srp_options_t client_opts;	/* cache between client steps */
81
--    char cIV[SRP_MAXBLOCKSIZE];	/* cache between client steps */
82
-+    unsigned char cIV[SRP_MAXBLOCKSIZE];	/* cache between client steps */
83
-     
84
-     char *salt;			/* password salt */
85
-     int saltlen;
86
-@@ -259,12 +257,12 @@ typedef struct context {
87
-     /* Layer foo */
88
-     unsigned layer;		/* bitmask of enabled layers */
89
-     const EVP_MD *hmac_md;	/* HMAC for integrity */
90
--    HMAC_CTX hmac_send_ctx;
91
--    HMAC_CTX hmac_recv_ctx;
92
-+    HMAC_CTX *hmac_send_ctx;
93
-+    HMAC_CTX *hmac_recv_ctx;
94
- 
95
-     const EVP_CIPHER *cipher;	/* cipher for confidentiality */
96
--    EVP_CIPHER_CTX cipher_enc_ctx;
97
--    EVP_CIPHER_CTX cipher_dec_ctx;
98
-+    EVP_CIPHER_CTX *cipher_enc_ctx;
99
-+    EVP_CIPHER_CTX *cipher_dec_ctx;
100
-     
101
-     /* replay detection sequence numbers */
102
-     int seqnum_out;
103
-@@ -279,6 +277,52 @@ typedef struct context {
104
-     
105
- } context_t;
106
- 
107
-+static void *OPENSSL_zalloc(size_t num)
108
-+{
109
-+    void *ret = OPENSSL_malloc(num);
110
-+
111
-+    if (ret != NULL)
112
-+        memset(ret, 0, num);
113
-+    return ret;
114
-+}
115
-+
116
-+HMAC_CTX *HMAC_CTX_new(void)
117
-+{
118
-+    HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
119
-+    if (ctx != NULL) {
120
-+        if (!HMAC_CTX_reset(ctx)) {
121
-+            HMAC_CTX_free(ctx);
122
-+            return NULL;
123
-+        }
124
-+    }
125
-+    return ctx;
126
-+}
127
-+
128
-+void HMAC_CTX_free(HMAC_CTX *ctx)
129
-+{
130
-+    if (ctx != NULL) {
131
-+        HMAC_CTX_cleanup(ctx);
132
-+        OPENSSL_free(ctx);
133
-+    }
134
-+}
135
-+
136
-+int HMAC_CTX_reset(HMAC_CTX *ctx)
137
-+{
138
-+    HMAC_CTX_init(ctx);
139
-+    return 1;
140
-+}
141
-+
142
-+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
143
-+{
144
-+        EVP_MD_CTX_cleanup(ctx);
145
-+            OPENSSL_free(ctx);
146
-+}
147
-+
148
-+EVP_MD_CTX *EVP_MD_CTX_new(void)
149
-+{
150
-+    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
151
-+}
152
-+
153
- static int srp_encode(void *context,
154
- 		      const struct iovec *invec,
155
- 		      unsigned numiov,
156
-@@ -317,12 +361,12 @@ static int srp_encode(void *context,
157
- 	inputlen = invec[i].iov_len;
158
-     
159
- 	if (text->layer & BIT_CONFIDENTIALITY) {
160
--	    unsigned enclen;
161
-+	    int enclen;
162
- 
163
- 	    /* encrypt the data into the output buffer */
164
--	    EVP_EncryptUpdate(&text->cipher_enc_ctx,
165
--			      text->encode_buf + *outputlen, &enclen,
166
--			      input, inputlen);
167
-+	    EVP_EncryptUpdate(text->cipher_enc_ctx,
168
-+			      (unsigned char *) text->encode_buf + *outputlen,
169
-+                              &enclen, (unsigned char *) input, inputlen);
170
- 	    *outputlen += enclen;
171
- 
172
- 	    /* switch the input to the encrypted data */
173
-@@ -337,11 +381,12 @@ static int srp_encode(void *context,
174
-     }
175
-     
176
-     if (text->layer & BIT_CONFIDENTIALITY) {
177
--	unsigned enclen;
178
-+	int enclen;
179
- 
180
- 	/* encrypt the last block of data into the output buffer */
181
--	EVP_EncryptFinal(&text->cipher_enc_ctx,
182
--			 text->encode_buf + *outputlen, &enclen);
183
-+	EVP_EncryptFinal(text->cipher_enc_ctx,
184
-+			 (unsigned char *) text->encode_buf + *outputlen,
185
-+                         &enclen);
186
- 	*outputlen += enclen;
187
-     }
188
- 
189
-@@ -349,18 +394,20 @@ static int srp_encode(void *context,
190
- 	unsigned hashlen;
191
- 
192
- 	/* hash the content */
193
--	HMAC_Update(&text->hmac_send_ctx, text->encode_buf+4, *outputlen-4);
194
-+	HMAC_Update(text->hmac_send_ctx,
195
-+                    (unsigned char *) text->encode_buf+4, *outputlen-4);
196
- 	
197
- 	if (text->layer & BIT_REPLAY_DETECTION) {
198
- 	    /* hash the sequence number */
199
- 	    tmpnum = htonl(text->seqnum_out);
200
--	    HMAC_Update(&text->hmac_send_ctx, (char *) &tmpnum, 4);
201
-+	    HMAC_Update(text->hmac_send_ctx, (unsigned char *) &tmpnum, 4);
202
- 	    
203
- 	    text->seqnum_out++;
204
- 	}
205
- 
206
- 	/* append the HMAC into the output buffer */
207
--	HMAC_Final(&text->hmac_send_ctx, text->encode_buf + *outputlen,
208
-+	HMAC_Final(text->hmac_send_ctx,
209
-+                   (unsigned char *) text->encode_buf + *outputlen,
210
- 		   &hashlen);
211
- 	*outputlen += hashlen;
212
-     }
213
-@@ -387,8 +434,8 @@ static int srp_decode_packet(void *conte
214
- 
215
-     if (text->layer & BIT_INTEGRITY) {
216
- 	const char *hash;
217
--	char myhash[EVP_MAX_MD_SIZE];
218
--	unsigned hashlen, myhashlen, i;
219
-+	unsigned char myhash[EVP_MAX_MD_SIZE];
220
-+	unsigned hashlen;
221
- 	unsigned long tmpnum;
222
- 
223
- 	hashlen = EVP_MD_size(text->hmac_md);
224
-@@ -405,25 +452,23 @@ static int srp_decode_packet(void *conte
225
- 	hash = input + inputlen;
226
- 
227
- 	/* create our own hash from the input */
228
--	HMAC_Update(&text->hmac_recv_ctx, input, inputlen);
229
-+	HMAC_Update(text->hmac_recv_ctx, (unsigned char *) input, inputlen);
230
- 	    
231
- 	if (text->layer & BIT_REPLAY_DETECTION) {
232
- 	    /* hash the sequence number */
233
- 	    tmpnum = htonl(text->seqnum_in);
234
--	    HMAC_Update(&text->hmac_recv_ctx, (char *) &tmpnum, 4);
235
-+	    HMAC_Update(text->hmac_recv_ctx, (unsigned char *) &tmpnum, 4);
236
- 		
237
- 	    text->seqnum_in++;
238
- 	}
239
- 	    
240
--	HMAC_Final(&text->hmac_recv_ctx, myhash, &myhashlen);
241
-+	HMAC_Final(text->hmac_recv_ctx, myhash, &hashlen);
242
- 
243
- 	/* compare hashes */
244
--	for (i = 0; i < hashlen; i++) {
245
--	    if ((myhashlen != hashlen) || (myhash[i] != hash[i])) {
246
--		SETERROR(text->utils, "Hash is incorrect\n");
247
--		return SASL_BADMAC;
248
--	    }
249
--	}
250
-+        if (memcmp(hash, myhash, hashlen)) {
251
-+            SETERROR(text->utils, "Hash is incorrect\n");
252
-+            return SASL_BADMAC;
253
-+        }
254
-     }
255
- 	
256
-     ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf),
257
-@@ -432,16 +477,17 @@ static int srp_decode_packet(void *conte
258
-     if (ret != SASL_OK) return ret;
259
- 	
260
-     if (text->layer & BIT_CONFIDENTIALITY) {
261
--	unsigned declen;
262
-+	int declen;
263
- 
264
- 	/* decrypt the data into the output buffer */
265
--	EVP_DecryptUpdate(&text->cipher_dec_ctx,
266
--			  text->decode_pkt_buf, &declen,
267
--			  (char *) input, inputlen);
268
-+	EVP_DecryptUpdate(text->cipher_dec_ctx,
269
-+			  (unsigned char *) text->decode_pkt_buf, &declen,
270
-+			  (unsigned char *) input, inputlen);
271
- 	*outputlen = declen;
272
- 	    
273
--	EVP_DecryptFinal(&text->cipher_dec_ctx,
274
--			 text->decode_pkt_buf + declen, &declen);
275
-+	EVP_DecryptFinal(text->cipher_dec_ctx,
276
-+			 (unsigned char *) text->decode_pkt_buf + declen,
277
-+                         &declen);
278
- 	*outputlen += declen;
279
-     } else {
280
- 	/* copy the raw input to the output */
281
-@@ -474,7 +520,8 @@ static int srp_decode(void *context,
282
- /*
283
-  * Convert a big integer to it's byte representation
284
-  */
285
--static int BigIntToBytes(BIGNUM *num, char *out, int maxoutlen, int *outlen)
286
-+static int BigIntToBytes(BIGNUM *num, unsigned char *out, int maxoutlen,
287
-+                         unsigned int *outlen)
288
- {
289
-     int len;
290
-     
291
-@@ -504,12 +551,12 @@ static int BigIntCmpWord(BIGNUM *a, BN_U
292
- /*
293
-  * Generate a random big integer.
294
-  */
295
--static void GetRandBigInt(BIGNUM *out)
296
-+static void GetRandBigInt(BIGNUM **out)
297
- {
298
--    BN_init(out);
299
-+    *out = BN_new();
300
-     
301
-     /* xxx likely should use sasl random funcs */
302
--    BN_rand(out, SRP_MAXBLOCKSIZE*8, 0, 0);
303
-+    BN_rand(*out, SRP_MAXBLOCKSIZE*8, 0, 0);
304
- }
305
- 
306
- #define MAX_BUFFER_LEN 2147483643
307
-@@ -624,7 +671,8 @@ static int MakeBuffer(const sasl_utils_t
308
- 	case 'm':
309
- 	    /* MPI */
310
- 	    mpi = va_arg(ap, BIGNUM *);
311
--	    r = BigIntToBytes(mpi, out+2, BN_num_bytes(mpi), &len);
312
-+	    r = BigIntToBytes(mpi, (unsigned char *) out+2,
313
-+                              BN_num_bytes(mpi), (unsigned *) &len);
314
- 	    if (r) goto done;
315
- 	    ns = htons(len);
316
- 	    memcpy(out, &ns, 2);	/* add 2 byte len (network order) */
317
-@@ -695,7 +743,7 @@ static int UnBuffer(const sasl_utils_t *
318
-     va_list ap;
319
-     char *p;
320
-     int r = SASL_OK, noalloc;
321
--    BIGNUM *mpi;
322
-+    BIGNUM **mpi;
323
-     char **os, **str;
324
-     uint32 *u;
325
-     unsigned short ns;
326
-@@ -757,9 +805,12 @@ static int UnBuffer(const sasl_utils_t *
327
- 		goto done;
328
- 	    }
329
- 	    
330
--	    mpi = va_arg(ap, BIGNUM *);
331
--	    BN_init(mpi);
332
--	    BN_bin2bn(buf, len, mpi);
333
-+	    mpi = va_arg(ap, BIGNUM **);
334
-+            if (mpi) {
335
-+                if (!*mpi) *mpi = BN_new();
336
-+                else BN_clear(*mpi);
337
-+                BN_bin2bn((unsigned char *) buf, len, *mpi);
338
-+            }
339
- 	    break;
340
- 
341
- 	case 'o':
342
-@@ -883,16 +934,17 @@ static int UnBuffer(const sasl_utils_t *
343
- /*
344
-  * Apply the hash function to the data specifed by the fmt string.
345
-  */
346
--static int MakeHash(const EVP_MD *md, unsigned char hash[], int *hashlen,
347
-+static int MakeHash(const EVP_MD *md,
348
-+                    unsigned char hash[], unsigned int *hashlen,
349
- 		    const char *fmt, ...)
350
- {
351
-     va_list ap;
352
-     char *p, buf[4096], *in;
353
--    int inlen;
354
--    EVP_MD_CTX mdctx;
355
-+    unsigned int inlen;
356
-+    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
357
-     int r = 0, hflag;
358
- 
359
--    EVP_DigestInit(&mdctx, md);
360
-+    EVP_DigestInit(mdctx, md);
361
- 
362
-     va_start(ap, fmt);
363
-     for (p = (char *) fmt; *p; p++) {
364
-@@ -910,7 +962,7 @@ static int MakeHash(const EVP_MD *md, un
365
- 		BIGNUM *mval = va_arg(ap, BIGNUM *);
366
- 
367
- 		in = buf;
368
--		r = BigIntToBytes(mval, buf, sizeof(buf)-1, &inlen);
369
-+		r = BigIntToBytes(mval, (unsigned char *) buf, sizeof(buf)-1, &inlen);
370
- 		if (r) goto done;
371
- 		break;
372
- 	    }
373
-@@ -947,47 +999,52 @@ static int MakeHash(const EVP_MD *md, un
374
- 
375
- 	if (hflag) {
376
- 	    /* hash data separately before adding to current hash */
377
--	    EVP_MD_CTX tmpctx;
378
-+	    EVP_MD_CTX *tmpctx = EVP_MD_CTX_new();
379
- 
380
--	    EVP_DigestInit(&tmpctx, md);
381
--	    EVP_DigestUpdate(&tmpctx, in, inlen);
382
--	    EVP_DigestFinal(&tmpctx, buf, &inlen);
383
-+	    EVP_DigestInit(tmpctx, md);
384
-+	    EVP_DigestUpdate(tmpctx, in, inlen);
385
-+	    EVP_DigestFinal(tmpctx, (unsigned char *) buf, &inlen);
386
-+            EVP_MD_CTX_free(tmpctx);
387
- 	    in = buf;
388
- 	}
389
- 
390
--	EVP_DigestUpdate(&mdctx, in, inlen);
391
-+	EVP_DigestUpdate(mdctx, in, inlen);
392
-     }
393
-   done:
394
-     va_end(ap);
395
- 
396
--    EVP_DigestFinal(&mdctx, hash, hashlen);
397
-+    EVP_DigestFinal(mdctx, hash, hashlen);
398
-+    EVP_MD_CTX_free(mdctx);
399
- 
400
-     return r;
401
- }
402
- 
403
- static int CalculateX(context_t *text, const char *salt, int saltlen, 
404
--		      const char *user, const char *pass, int passlen, 
405
--		      BIGNUM *x)
406
-+		      const char *user, const unsigned char *pass, int passlen, 
407
-+		      BIGNUM **x)
408
- {
409
--    char hash[EVP_MAX_MD_SIZE];
410
--    int hashlen;
411
-+    unsigned char hash[EVP_MAX_MD_SIZE];
412
-+    unsigned int hashlen;
413
-     
414
-     /* x = H(salt | H(user | ':' | pass)) */
415
-     MakeHash(text->md, hash, &hashlen, "%s:%o", user, passlen, pass);
416
-     MakeHash(text->md, hash, &hashlen, "%o%o", saltlen, salt, hashlen, hash);
417
-     
418
--    BN_init(x);
419
--    BN_bin2bn(hash, hashlen, x);
420
-+    *x = BN_new();
421
-+    BN_bin2bn(hash, hashlen, *x);
422
-     
423
-     return SASL_OK;
424
- }
425
- 
426
- static int CalculateM1(context_t *text, BIGNUM *N, BIGNUM *g,
427
- 		       char *U, char *salt, int saltlen,
428
--		       BIGNUM *A, BIGNUM *B, char *K, int Klen,
429
--		       char *I, char *L, char *M1, int *M1len)
430
-+		       BIGNUM *A, BIGNUM *B,
431
-+                       unsigned char *K, unsigned int Klen,
432
-+		       char *I, char *L,
433
-+                       unsigned char *M1, unsigned int *M1len)
434
- {
435
--    int r, i, len;
436
-+    int r;
437
-+    unsigned int i, len;
438
-     unsigned char Nhash[EVP_MAX_MD_SIZE];
439
-     unsigned char ghash[EVP_MAX_MD_SIZE];
440
-     unsigned char Ng[EVP_MAX_MD_SIZE];
441
-@@ -1010,9 +1067,10 @@ static int CalculateM1(context_t *text,
442
- }
443
- 
444
- static int CalculateM2(context_t *text, BIGNUM *A,
445
--		       char *M1, int M1len, char *K, int Klen,
446
-+		       unsigned char *M1, unsigned int M1len,
447
-+                       unsigned char *K, unsigned int Klen,
448
- 		       char *I, char *o, char *sid, uint32 ttl,
449
--		       char *M2, int *M2len)
450
-+		       unsigned char *M2, unsigned int *M2len)
451
- {
452
-     int r;
453
-     
454
-@@ -1386,7 +1444,8 @@ static int SetMDA(srp_options_t *opts, c
455
-  * Setup the selected security layer.
456
-  */
457
- static int LayerInit(srp_options_t *opts, context_t *text,
458
--		     sasl_out_params_t *oparams, char *enc_IV, char *dec_IV,
459
-+		     sasl_out_params_t *oparams,
460
-+                     unsigned char *enc_IV, unsigned char *dec_IV,
461
- 		     unsigned maxbufsize)
462
- {
463
-     layer_option_t *opt;
464
-@@ -1431,8 +1490,10 @@ static int LayerInit(srp_options_t *opts
465
- 
466
- 	/* Initialize the HMACs */
467
- 	text->hmac_md = EVP_get_digestbyname(opt->evp_name);
468
--	HMAC_Init(&text->hmac_send_ctx, text->K, text->Klen, text->hmac_md);
469
--	HMAC_Init(&text->hmac_recv_ctx, text->K, text->Klen, text->hmac_md);
470
-+        text->hmac_send_ctx = HMAC_CTX_new();
471
-+	HMAC_Init_ex(text->hmac_send_ctx, text->K, text->Klen, text->hmac_md, NULL);
472
-+        text->hmac_recv_ctx = HMAC_CTX_new();
473
-+	HMAC_Init_ex(text->hmac_recv_ctx, text->K, text->Klen, text->hmac_md, NULL);
474
- 	
475
- 	/* account for HMAC */
476
- 	oparams->maxoutbuf -= EVP_MD_size(text->hmac_md);
477
-@@ -1456,11 +1517,13 @@ static int LayerInit(srp_options_t *opts
478
- 	/* Initialize the ciphers */
479
- 	text->cipher = EVP_get_cipherbyname(opt->evp_name);
480
- 
481
--	EVP_CIPHER_CTX_init(&text->cipher_enc_ctx);
482
--	EVP_EncryptInit(&text->cipher_enc_ctx, text->cipher, text->K, enc_IV);
483
--
484
--	EVP_CIPHER_CTX_init(&text->cipher_dec_ctx);
485
--	EVP_DecryptInit(&text->cipher_dec_ctx, text->cipher, text->K, dec_IV);
486
-+        text->cipher_enc_ctx = EVP_CIPHER_CTX_new();
487
-+	EVP_CIPHER_CTX_init(text->cipher_enc_ctx);
488
-+	EVP_EncryptInit(text->cipher_enc_ctx, text->cipher, text->K, enc_IV);
489
-+
490
-+        text->cipher_dec_ctx = EVP_CIPHER_CTX_new();
491
-+	EVP_CIPHER_CTX_init(text->cipher_dec_ctx);
492
-+	EVP_DecryptInit(text->cipher_dec_ctx, text->cipher, text->K, dec_IV);
493
-     }
494
-     
495
-     return SASL_OK;
496
-@@ -1469,13 +1532,13 @@ static int LayerInit(srp_options_t *opts
497
- static void LayerCleanup(context_t *text)
498
- {
499
-     if (text->layer & BIT_INTEGRITY) {
500
--	HMAC_cleanup(&text->hmac_send_ctx);
501
--	HMAC_cleanup(&text->hmac_recv_ctx);
502
-+	HMAC_CTX_free(text->hmac_send_ctx);
503
-+	HMAC_CTX_free(text->hmac_recv_ctx);
504
-     }
505
- 
506
-     if (text->layer & BIT_CONFIDENTIALITY) {
507
--	EVP_CIPHER_CTX_cleanup(&text->cipher_enc_ctx);
508
--	EVP_CIPHER_CTX_cleanup(&text->cipher_dec_ctx);
509
-+	EVP_CIPHER_CTX_free(text->cipher_enc_ctx);
510
-+	EVP_CIPHER_CTX_free(text->cipher_dec_ctx);
511
-     }
512
- }
513
-     
514
-@@ -1490,13 +1553,13 @@ static void srp_common_mech_dispose(void
515
-     
516
-     if (!text) return;
517
-     
518
--    BN_clear_free(&text->N);
519
--    BN_clear_free(&text->g);
520
--    BN_clear_free(&text->v);
521
--    BN_clear_free(&text->b);
522
--    BN_clear_free(&text->B);
523
--    BN_clear_free(&text->a);
524
--    BN_clear_free(&text->A);
525
-+    BN_clear_free(text->N);
526
-+    BN_clear_free(text->g);
527
-+    BN_clear_free(text->v);
528
-+    BN_clear_free(text->b);
529
-+    BN_clear_free(text->B);
530
-+    BN_clear_free(text->a);
531
-+    BN_clear_free(text->A);
532
-     
533
-     if (text->authid)		utils->free(text->authid);
534
-     if (text->userid)		utils->free(text->userid);
535
-@@ -1534,16 +1597,16 @@ srp_common_mech_free(void *global_contex
536
-  *
537
-  * All arithmetic is done modulo N
538
-  */
539
--static int generate_N_and_g(BIGNUM *N, BIGNUM *g)
540
-+static int generate_N_and_g(BIGNUM **N, BIGNUM **g)
541
- {
542
-     int result;
543
--    
544
--    BN_init(N);
545
--    result = BN_hex2bn(&N, Ng_tab[NUM_Ng-1].N);
546
-+
547
-+    *N = BN_new();
548
-+    result = BN_hex2bn(N, Ng_tab[NUM_Ng-1].N);
549
-     if (!result) return SASL_FAIL;
550
-     
551
--    BN_init(g);
552
--    BN_set_word(g, Ng_tab[NUM_Ng-1].g);
553
-+    *g = BN_new();
554
-+    BN_set_word(*g, Ng_tab[NUM_Ng-1].g);
555
-     
556
-     return SASL_OK;
557
- }
558
-@@ -1551,10 +1614,10 @@ static int generate_N_and_g(BIGNUM *N, B
559
- static int CalculateV(context_t *text,
560
- 		      BIGNUM *N, BIGNUM *g,
561
- 		      const char *user,
562
--		      const char *pass, unsigned passlen,
563
--		      BIGNUM *v, char **salt, int *saltlen)
564
-+		      const unsigned char *pass, unsigned passlen,
565
-+		      BIGNUM **v, char **salt, int *saltlen)
566
- {
567
--    BIGNUM x;
568
-+    BIGNUM *x = NULL;
569
-     BN_CTX *ctx = BN_CTX_new();
570
-     int r;
571
-     
572
-@@ -1572,40 +1635,41 @@ static int CalculateV(context_t *text,
573
-     }
574
-     
575
-     /* v = g^x % N */
576
--    BN_init(v);
577
--    BN_mod_exp(v, g, &x, N, ctx);
578
-+    *v = BN_new();
579
-+    BN_mod_exp(*v, g, x, N, ctx);
580
-     
581
-     BN_CTX_free(ctx);
582
--    BN_clear_free(&x);
583
-+    BN_clear_free(x);
584
-     
585
-     return r;   
586
- }
587
- 
588
- static int CalculateB(context_t *text  __attribute__((unused)),
589
--		      BIGNUM *v, BIGNUM *N, BIGNUM *g, BIGNUM *b, BIGNUM *B)
590
-+		      BIGNUM *v, BIGNUM *N, BIGNUM *g, BIGNUM **b, BIGNUM **B)
591
- {
592
--    BIGNUM v3;
593
-+    BIGNUM *v3 = BN_new();
594
-     BN_CTX *ctx = BN_CTX_new();
595
-     
596
-     /* Generate b */
597
-     GetRandBigInt(b);
598
- 	
599
-     /* Per [SRP]: make sure b > log[g](N) -- g is always 2 */
600
--    BN_add_word(b, BN_num_bits(N));
601
-+    BN_add_word(*b, BN_num_bits(N));
602
- 	
603
-     /* B = (3v + g^b) % N */
604
--    BN_init(&v3);
605
--    BN_set_word(&v3, 3);
606
--    BN_mod_mul(&v3, &v3, v, N, ctx);
607
--    BN_init(B);
608
--    BN_mod_exp(B, g, b, N, ctx);
609
-+    BN_set_word(v3, 3);
610
-+    BN_mod_mul(v3, v3, v, N, ctx);
611
-+
612
-+    *B = BN_new();
613
-+    BN_mod_exp(*B, g, *b, N, ctx);
614
- #if OPENSSL_VERSION_NUMBER >= 0x00907000L
615
--    BN_mod_add(B, B, &v3, N, ctx);
616
-+    BN_mod_add(*B, *B, v3, N, ctx);
617
- #else
618
--    BN_add(B, B, &v3);
619
--    BN_mod(B, B, N, ctx);
620
-+    BN_add(*B, *B, v3);
621
-+    BN_mod(*B, *B, N, ctx);
622
- #endif
623
- 
624
-+    BN_clear_free(v3);
625
-     BN_CTX_free(ctx);
626
-     
627
-     return SASL_OK;
628
-@@ -1613,13 +1677,13 @@ static int CalculateB(context_t *text  _
629
- 	
630
- static int ServerCalculateK(context_t *text, BIGNUM *v,
631
- 			    BIGNUM *N, BIGNUM *A, BIGNUM *b, BIGNUM *B,
632
--			    char *K, int *Klen)
633
-+			    unsigned char *K, unsigned int *Klen)
634
- {
635
-     unsigned char hash[EVP_MAX_MD_SIZE];
636
--    int hashlen;
637
--    BIGNUM u;
638
--    BIGNUM base;
639
--    BIGNUM S;
640
-+    unsigned int hashlen;
641
-+    BIGNUM *u = BN_new();
642
-+    BIGNUM *base = BN_new();
643
-+    BIGNUM *S = BN_new();
644
-     BN_CTX *ctx = BN_CTX_new();
645
-     int r;
646
-     
647
-@@ -1627,50 +1691,47 @@ static int ServerCalculateK(context_t *t
648
-     r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B);
649
-     if (r) return r;
650
- 	
651
--    BN_init(&u);
652
--    BN_bin2bn(hash, hashlen, &u);
653
-+    BN_bin2bn(hash, hashlen, u);
654
- 	
655
-     /* S = (Av^u) ^ b % N */
656
--    BN_init(&base);
657
--    BN_mod_exp(&base, v, &u, N, ctx);
658
--    BN_mod_mul(&base, &base, A, N, ctx);
659
-+    BN_mod_exp(base, v, u, N, ctx);
660
-+    BN_mod_mul(base, base, A, N, ctx);
661
-     
662
--    BN_init(&S);
663
--    BN_mod_exp(&S, &base, b, N, ctx);
664
-+    BN_mod_exp(S, base, b, N, ctx);
665
-     
666
-     /* per Tom Wu: make sure Av^u != 1 (mod N) */
667
--    if (BN_is_one(&base)) {
668
-+    if (BN_is_one(base)) {
669
- 	SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n");
670
- 	r = SASL_BADPROT;
671
- 	goto err;
672
-     }
673
-     
674
-     /* per Tom Wu: make sure Av^u != -1 (mod N) */
675
--    BN_add_word(&base, 1);
676
--    if (BN_cmp(&S, N) == 0) {
677
-+    BN_add_word(base, 1);
678
-+    if (BN_cmp(S, N) == 0) {
679
- 	SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n");
680
- 	r = SASL_BADPROT;
681
- 	goto err;
682
-     }
683
-     
684
-     /* K = H(S) */
685
--    r = MakeHash(text->md, K, Klen, "%m", &S);
686
-+    r = MakeHash(text->md, K, Klen, "%m", S);
687
-     if (r) goto err;
688
-     
689
-     r = SASL_OK;
690
-     
691
-   err:
692
-     BN_CTX_free(ctx);
693
--    BN_clear_free(&u);
694
--    BN_clear_free(&base);
695
--    BN_clear_free(&S);
696
-+    BN_clear_free(u);
697
-+    BN_clear_free(base);
698
-+    BN_clear_free(S);
699
-     
700
-     return r;
701
- }
702
- 
703
- static int ParseUserSecret(const sasl_utils_t *utils,
704
- 			   char *secret, size_t seclen,
705
--			   char **mda, BIGNUM *v, char **salt, int *saltlen)
706
-+			   char **mda, BIGNUM **v, char **salt, int *saltlen)
707
- {
708
-     int r;
709
-     
710
-@@ -1678,7 +1739,7 @@ static int ParseUserSecret(const sasl_ut
711
-      *
712
-      *  { utf8(mda) mpi(v) os(salt) }  (base64 encoded)
713
-      */
714
--    r = utils->decode64(secret, seclen, secret, seclen, &seclen);
715
-+    r = utils->decode64(secret, seclen, secret, seclen, (unsigned *) &seclen);
716
- 
717
-     if (!r)
718
- 	r = UnBuffer(utils, secret, seclen, "%s%m%o", mda, v, saltlen, salt);
719
-@@ -1919,8 +1980,8 @@ static int srp_server_mech_step1(context
720
- 	    goto cleanup;
721
- 	}
722
- 	
723
--	result = CalculateV(text, &text->N, &text->g, text->authid,
724
--			    auxprop_values[1].values[0], len,
725
-+	result = CalculateV(text, text->N, text->g, text->authid,
726
-+			    (unsigned char *) auxprop_values[1].values[0], len,
727
- 			    &text->v, &text->salt, &text->saltlen);
728
- 	if (result) {
729
- 	    params->utils->seterror(params->utils->conn, 0, 
730
-@@ -1938,8 +1999,7 @@ static int srp_server_mech_step1(context
731
-     params->utils->prop_erase(params->propctx, password_request[1]);
732
-     
733
-     /* Calculate B */
734
--    result = CalculateB(text, &text->v, &text->N, &text->g,
735
--			&text->b, &text->B);
736
-+    result = CalculateB(text, text->v, text->N, text->g, &text->b, &text->B);
737
-     if (result) {
738
- 	params->utils->seterror(params->utils->conn, 0, 
739
- 				"Error calculating B");
740
-@@ -1967,8 +2027,8 @@ static int srp_server_mech_step1(context
741
-      */
742
-     result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
743
- 			serveroutlen, "%c%m%m%o%m%s",
744
--			0x00, &text->N, &text->g, text->saltlen, text->salt,
745
--			&text->B, text->server_options);
746
-+			0x00, text->N, text->g, text->saltlen, text->salt,
747
-+			text->B, text->server_options);
748
-     if (result) {
749
- 	params->utils->seterror(params->utils->conn, 0, 
750
- 				"Error creating SRP buffer from data in step 1");
751
-@@ -1997,15 +2057,15 @@ static int srp_server_mech_step2(context
752
- 			sasl_out_params_t *oparams)
753
- {
754
-     int result;    
755
--    char *M1 = NULL, *cIV = NULL; /* don't free */
756
--    int M1len, cIVlen;
757
-+    unsigned char *M1 = NULL, *cIV = NULL; /* don't free */
758
-+    unsigned int M1len, cIVlen;
759
-     srp_options_t client_opts;
760
--    char myM1[EVP_MAX_MD_SIZE];
761
--    int myM1len;
762
--    int i;
763
--    char M2[EVP_MAX_MD_SIZE];
764
--    int M2len;
765
--    char sIV[SRP_MAXBLOCKSIZE];
766
-+    unsigned char myM1[EVP_MAX_MD_SIZE];
767
-+    unsigned int myM1len;
768
-+    unsigned int i;
769
-+    unsigned char M2[EVP_MAX_MD_SIZE];
770
-+    unsigned int M2len;
771
-+    unsigned char sIV[SRP_MAXBLOCKSIZE];
772
-     
773
-     /* Expect:
774
-      *
775
-@@ -2027,7 +2087,7 @@ static int srp_server_mech_step2(context
776
-     }
777
-     
778
-     /* Per [SRP]: reject A <= 0 */
779
--    if (BigIntCmpWord(&text->A, 0) <= 0) {
780
-+    if (BigIntCmpWord(text->A, 0) <= 0) {
781
- 	SETERROR(params->utils, "Illegal value for 'A'\n");
782
- 	result = SASL_BADPROT;
783
- 	goto cleanup;
784
-@@ -2058,8 +2118,8 @@ static int srp_server_mech_step2(context
785
-     }
786
- 
787
-     /* Calculate K */
788
--    result = ServerCalculateK(text, &text->v, &text->N, &text->A,
789
--			      &text->b, &text->B, text->K, &text->Klen);
790
-+    result = ServerCalculateK(text, text->v, text->N, text->A,
791
-+			      text->b, text->B, text->K, &text->Klen);
792
-     if (result) {
793
- 	params->utils->seterror(params->utils->conn, 0, 
794
- 				"Error calculating K");
795
-@@ -2067,8 +2127,8 @@ static int srp_server_mech_step2(context
796
-     }
797
-     
798
-     /* See if M1 is correct */
799
--    result = CalculateM1(text, &text->N, &text->g, text->authid,
800
--			 text->salt, text->saltlen, &text->A, &text->B,
801
-+    result = CalculateM1(text, text->N, text->g, text->authid,
802
-+			 text->salt, text->saltlen, text->A, text->B,
803
- 			 text->K, text->Klen, text->userid,
804
- 			 text->server_options, myM1, &myM1len);
805
-     if (result) {
806
-@@ -2095,7 +2155,7 @@ static int srp_server_mech_step2(context
807
-     }
808
-     
809
-     /* calculate M2 to send */
810
--    result = CalculateM2(text, &text->A, M1, M1len, text->K, text->Klen,
811
-+    result = CalculateM2(text, text->A, M1, M1len, text->K, text->Klen,
812
- 			 text->userid, text->client_options, "", 0,
813
- 			 M2, &M2len);
814
-     if (result) {
815
-@@ -2105,7 +2165,7 @@ static int srp_server_mech_step2(context
816
-     }
817
-     
818
-     /* Create sIV (server initial vector) */
819
--    text->utils->rand(text->utils->rpool, sIV, sizeof(sIV));
820
-+    text->utils->rand(text->utils->rpool, (char *) sIV, sizeof(sIV));
821
-     
822
-     /*
823
-      * Send out:
824
-@@ -2230,20 +2290,20 @@ static int srp_setpass(void *glob_contex
825
-     r = _plug_make_fulluser(sparams->utils, &user, user_only, realm);
826
- 
827
-     if (r) {
828
--	goto end;
829
-+	goto cleanup;
830
-     }
831
- 
832
-     if ((flags & SASL_SET_DISABLE) || pass == NULL) {
833
- 	sec = NULL;
834
-     } else {
835
--	context_t *text;
836
--	BIGNUM N;
837
--	BIGNUM g;
838
--	BIGNUM v;
839
-+	context_t *text = NULL;
840
-+	BIGNUM *N = NULL;
841
-+	BIGNUM *g = NULL;
842
-+	BIGNUM *v = NULL;
843
- 	char *salt;
844
- 	int saltlen;
845
- 	char *buffer = NULL;
846
--	int bufferlen, alloclen, encodelen;
847
-+	unsigned int bufferlen, alloclen, encodelen;
848
- 	
849
- 	text = sparams->utils->malloc(sizeof(context_t));
850
- 	if (text == NULL) {
851
-@@ -2264,7 +2324,8 @@ static int srp_setpass(void *glob_contex
852
- 	}
853
- 
854
- 	/* user is a full username here */
855
--	r = CalculateV(text, &N, &g, user, pass, passlen, &v, &salt, &saltlen);
856
-+	r = CalculateV(text, N, g, user,
857
-+                       (unsigned char *) pass, passlen, &v, &salt, &saltlen);
858
- 	if (r) {
859
- 	    sparams->utils->seterror(sparams->utils->conn, 0, 
860
- 				     "Error calculating v");
861
-@@ -2296,16 +2357,16 @@ static int srp_setpass(void *glob_contex
862
- 	    r = SASL_NOMEM;
863
- 	    goto end;
864
- 	}
865
--	sparams->utils->encode64(buffer, bufferlen, sec->data, alloclen,
866
-+	sparams->utils->encode64(buffer, bufferlen, (char *) sec->data, alloclen,
867
- 				 &encodelen);
868
- 	sec->len = encodelen;
869
- 	
870
- 	/* Clean everything up */
871
-       end:
872
- 	if (buffer) sparams->utils->free((void *) buffer);
873
--	BN_clear_free(&N);
874
--	BN_clear_free(&g);
875
--	BN_clear_free(&v);
876
-+	BN_clear_free(N);
877
-+	BN_clear_free(g);
878
-+	BN_clear_free(v);
879
- 	sparams->utils->free(text);
880
- 	
881
- 	if (r) return r;
882
-@@ -2319,7 +2380,7 @@ static int srp_setpass(void *glob_contex
883
- 	r = sparams->utils->prop_request(propctx, store_request);
884
-     if (!r)
885
- 	r = sparams->utils->prop_set(propctx, "cmusaslsecretSRP",
886
--				     (sec ? sec->data : NULL),
887
-+				     (char *) (sec ? sec->data : NULL),
888
- 				     (sec ? sec->len : 0));
889
-     if (!r)
890
- 	r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user);
891
-@@ -2475,7 +2536,7 @@ static int check_N_and_g(const sasl_util
892
- }
893
- 
894
- static int CalculateA(context_t *text  __attribute__((unused)),
895
--		      BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A)
896
-+		      BIGNUM *N, BIGNUM *g, BIGNUM **a, BIGNUM **A)
897
- {
898
-     BN_CTX *ctx = BN_CTX_new();
899
-     
900
-@@ -2483,11 +2544,11 @@ static int CalculateA(context_t *text  _
901
-     GetRandBigInt(a);
902
- 	
903
-     /* Per [SRP]: make sure a > log[g](N) -- g is always 2 */
904
--    BN_add_word(a, BN_num_bits(N));
905
-+    BN_add_word(*a, BN_num_bits(N));
906
- 	
907
-     /* A = g^a % N */
908
--    BN_init(A);
909
--    BN_mod_exp(A, g, a, N, ctx);
910
-+    *A = BN_new();
911
-+    BN_mod_exp(*A, g, *a, N, ctx);
912
- 
913
-     BN_CTX_free(ctx);
914
-     
915
-@@ -2495,30 +2556,30 @@ static int CalculateA(context_t *text  _
916
- }
917
- 	
918
- static int ClientCalculateK(context_t *text, char *salt, int saltlen,
919
--			    char *user, char *pass, int passlen,
920
-+			    char *user, unsigned char *pass, int passlen,
921
- 			    BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A,
922
--			    BIGNUM *B, char *K, int *Klen)
923
-+			    BIGNUM *B, unsigned char *K, unsigned int *Klen)
924
- {
925
-     int r;
926
-     unsigned char hash[EVP_MAX_MD_SIZE];
927
--    int hashlen;
928
--    BIGNUM x;
929
--    BIGNUM u;
930
--    BIGNUM aux;
931
--    BIGNUM gx;
932
--    BIGNUM gx3;
933
--    BIGNUM base;
934
--    BIGNUM S;
935
-+    unsigned int hashlen;
936
-+    BIGNUM *x = NULL;
937
-+    BIGNUM *u = BN_new();
938
-+    BIGNUM *aux = BN_new();
939
-+    BIGNUM *gx = BN_new();
940
-+    BIGNUM *gx3 = BN_new();
941
-+    BIGNUM *base = BN_new();
942
-+    BIGNUM *S = BN_new();
943
-     BN_CTX *ctx = BN_CTX_new();
944
-     
945
-     /* u = H(A | B) */
946
-     r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B);
947
-     if (r) goto err;
948
--    BN_init(&u);
949
--    BN_bin2bn(hash, hashlen, &u);
950
-+    u = BN_new();
951
-+    BN_bin2bn(hash, hashlen, u);
952
-     
953
-     /* per Tom Wu: make sure u != 0 */
954
--    if (BN_is_zero(&u)) {
955
-+    if (BN_is_zero(u)) {
956
- 	SETERROR(text->utils, "SRP: Illegal value for 'u'\n");
957
- 	r = SASL_BADPROT;
958
- 	goto err;
959
-@@ -2530,48 +2591,43 @@ static int ClientCalculateK(context_t *t
960
-     if (r) return r;
961
-     
962
-     /* a + ux */
963
--    BN_init(&aux);
964
--    BN_mul(&aux, &u, &x, ctx);
965
--    BN_add(&aux, &aux, a);
966
-+    BN_mul(aux, u, x, ctx);
967
-+    BN_add(aux, aux, a);
968
-     
969
-     /* gx3 = 3(g^x) % N */
970
--    BN_init(&gx);
971
--    BN_mod_exp(&gx, g, &x, N, ctx);
972
--    BN_init(&gx3);
973
--    BN_set_word(&gx3, 3);
974
--    BN_mod_mul(&gx3, &gx3, &gx, N, ctx);
975
-+    BN_mod_exp(gx, g, x, N, ctx);
976
-+    BN_set_word(gx3, 3);
977
-+    BN_mod_mul(gx3, gx3, gx, N, ctx);
978
-     
979
-     /* base = (B - 3(g^x)) % N */
980
--    BN_init(&base);
981
- #if OPENSSL_VERSION_NUMBER >= 0x00907000L
982
--    BN_mod_sub(&base, B, &gx3, N, ctx);
983
-+    BN_mod_sub(base, B, gx3, N, ctx);
984
- #else
985
--    BN_sub(&base, B, &gx3);
986
--    BN_mod(&base, &base, N, ctx);
987
--    if (BigIntCmpWord(&base, 0) < 0) {
988
--	BN_add(&base, &base, N);
989
-+    BN_sub(base, B, gx3);
990
-+    BN_mod(base, base, N, ctx);
991
-+    if (BigIntCmpWord(base, 0) < 0) {
992
-+	BN_add(base, base, N);
993
-     }
994
- #endif
995
-     
996
-     /* S = base^aux % N */
997
--    BN_init(&S);
998
--    BN_mod_exp(&S, &base, &aux, N, ctx);
999
-+    BN_mod_exp(S, base, aux, N, ctx);
1000
-     
1001
-     /* K = H(S) */
1002
--    r = MakeHash(text->md, K, Klen, "%m", &S);
1003
-+    r = MakeHash(text->md, K, Klen, "%m", S);
1004
-     if (r) goto err;
1005
-     
1006
-     r = SASL_OK;
1007
-     
1008
-   err:
1009
-     BN_CTX_free(ctx);
1010
--    BN_clear_free(&x);
1011
--    BN_clear_free(&u);
1012
--    BN_clear_free(&aux);
1013
--    BN_clear_free(&gx);
1014
--    BN_clear_free(&gx3);
1015
--    BN_clear_free(&base);
1016
--    BN_clear_free(&S);
1017
-+    BN_clear_free(x);
1018
-+    BN_clear_free(u);
1019
-+    BN_clear_free(aux);
1020
-+    BN_clear_free(gx);
1021
-+    BN_clear_free(gx3);
1022
-+    BN_clear_free(base);
1023
-+    BN_clear_free(S);
1024
-     
1025
-     return r;
1026
- }
1027
-@@ -2709,7 +2765,7 @@ static int srp_client_mech_new(void *glo
1028
-     }
1029
-     
1030
-     memset(text, 0, sizeof(context_t));
1031
--    
1032
-+
1033
-     text->state = 1;
1034
-     text->utils = params->utils;
1035
- 
1036
-@@ -2866,7 +2922,7 @@ srp_client_mech_step2(context_t *text,
1037
-     }
1038
- 
1039
-     /* Check N and g to see if they are one of the recommended pairs */
1040
--    result = check_N_and_g(params->utils, &text->N, &text->g);
1041
-+    result = check_N_and_g(params->utils, text->N, text->g);
1042
-     if (result) {
1043
- 	params->utils->log(NULL, SASL_LOG_ERR,
1044
- 			   "Values of 'N' and 'g' are not recommended\n");
1045
-@@ -2874,7 +2930,7 @@ srp_client_mech_step2(context_t *text,
1046
-     }
1047
-     
1048
-     /* Per [SRP]: reject B <= 0, B >= N */
1049
--    if (BigIntCmpWord(&text->B, 0) <= 0 || BN_cmp(&text->B, &text->N) >= 0) {
1050
-+    if (BigIntCmpWord(text->B, 0) <= 0 || BN_cmp(text->B, text->N) >= 0) {
1051
- 	SETERROR(params->utils, "Illegal value for 'B'\n");
1052
- 	result = SASL_BADPROT;
1053
- 	goto cleanup;
1054
-@@ -2913,7 +2969,7 @@ srp_client_mech_step2(context_t *text,
1055
-     }
1056
- 
1057
-     /* Calculate A */
1058
--    result = CalculateA(text, &text->N, &text->g, &text->a, &text->A);
1059
-+    result = CalculateA(text, text->N, text->g, &text->a, &text->A);
1060
-     if (result) {
1061
- 	params->utils->seterror(params->utils->conn, 0, 
1062
- 				"Error calculating A");
1063
-@@ -2924,7 +2980,7 @@ srp_client_mech_step2(context_t *text,
1064
-     result = ClientCalculateK(text, text->salt, text->saltlen,
1065
- 			      (char *) oparams->authid, 
1066
- 			      text->password->data, text->password->len,
1067
--			      &text->N, &text->g, &text->a, &text->A, &text->B,
1068
-+			      text->N, text->g, text->a, text->A, text->B,
1069
- 			      text->K, &text->Klen);
1070
-     if (result) {
1071
- 	params->utils->log(NULL, SASL_LOG_ERR,
1072
-@@ -2933,8 +2989,8 @@ srp_client_mech_step2(context_t *text,
1073
-     }
1074
-     
1075
-     /* Calculate M1 (client evidence) */
1076
--    result = CalculateM1(text, &text->N, &text->g, (char *) oparams->authid,
1077
--			 text->salt, text->saltlen, &text->A, &text->B,
1078
-+    result = CalculateM1(text, text->N, text->g, (char *) oparams->authid,
1079
-+			 text->salt, text->saltlen, text->A, text->B,
1080
- 			 text->K, text->Klen, (char *) oparams->user,
1081
- 			 text->server_options, text->M1, &text->M1len);
1082
-     if (result) {
1083
-@@ -2944,7 +3000,7 @@ srp_client_mech_step2(context_t *text,
1084
-     }
1085
- 
1086
-     /* Create cIV (client initial vector) */
1087
--    text->utils->rand(text->utils->rpool, text->cIV, sizeof(text->cIV));
1088
-+    text->utils->rand(text->utils->rpool, (char *) text->cIV, sizeof(text->cIV));
1089
-     
1090
-     /* Send out:
1091
-      *
1092
-@@ -2957,7 +3013,7 @@ srp_client_mech_step2(context_t *text,
1093
-      */
1094
-     result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
1095
- 			clientoutlen, "%m%o%s%o",
1096
--			&text->A, text->M1len, text->M1, text->client_options,
1097
-+			text->A, text->M1len, text->M1, text->client_options,
1098
- 			sizeof(text->cIV), text->cIV);
1099
-     if (result) {
1100
- 	params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
1101
-@@ -2985,13 +3041,13 @@ srp_client_mech_step3(context_t *text,
1102
- 		      sasl_out_params_t *oparams)
1103
- {
1104
-     int result;    
1105
--    char *M2 = NULL, *sIV = NULL; /* don't free */
1106
-+    unsigned char *M2 = NULL, *sIV = NULL; /* don't free */
1107
-     char *sid = NULL;
1108
--    int M2len, sIVlen;
1109
-+    unsigned int M2len, sIVlen;
1110
-     uint32 ttl;
1111
--    int i;
1112
--    char myM2[EVP_MAX_MD_SIZE];
1113
--    int myM2len;
1114
-+    unsigned int i;
1115
-+    unsigned char myM2[EVP_MAX_MD_SIZE];
1116
-+    unsigned int myM2len;
1117
-     
1118
-     /* Expect:
1119
-      *
1120
-@@ -3012,7 +3068,7 @@ srp_client_mech_step3(context_t *text,
1121
-     }
1122
- 
1123
-     /* calculate our own M2 */
1124
--    result = CalculateM2(text, &text->A, text->M1, text->M1len,
1125
-+    result = CalculateM2(text, text->A, text->M1, text->M1len,
1126
- 			 text->K, text->Klen, (char *) oparams->user,
1127
- 			 text->client_options, "", 0,
1128
- 			 myM2, &myM2len);
1129
-@@ -3182,3 +3238,4 @@ int srp_client_plug_init(const sasl_util
1130
-     
1131
-     return SASL_OK;
1132
- }
1133
-+
1
+diff -rupN cyrus-sasl-2.1.26/plugins/srp.c cyrus-sasl-2.1.26-new/plugins/srp.c
2
+--- cyrus-sasl-2.1.26/plugins/srp.c	2012-10-12 07:05:48.000000000 -0700
3
+@@ -1,10 +1,9 @@
4
+ /* SRP SASL plugin
5
+  * Ken Murchison
6
+  * Tim Martin  3/17/00
7
+- * $Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $
8
+  */
9
+ /* 
10
+- * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
11
++ * Copyright (c) 1998-2016 Carnegie Mellon University.  All rights reserved.
12
+  *
13
+  * Redistribution and use in source and binary forms, with or without
14
+  * modification, are permitted provided that the following conditions
15
+@@ -22,12 +21,13 @@
16
+  *    endorse or promote products derived from this software without
17
+  *    prior written permission. For permission or any other legal
18
+  *    details, please contact  
19
+- *      Office of Technology Transfer
20
+  *      Carnegie Mellon University
21
+- *      5000 Forbes Avenue
22
+- *      Pittsburgh, PA  15213-3890
23
+- *      (412) 268-4387, fax: (412) 268-7395
24
+- *      tech-transfer@andrew.cmu.edu
25
++ *      Center for Technology Transfer and Enterprise Creation
26
++ *      4615 Forbes Avenue
27
++ *      Suite 302
28
++ *      Pittsburgh, PA  15213
29
++ *      (412) 268-7393, fax: (412) 268-7395
30
++ *      innovation@andrew.cmu.edu
31
+  *
32
+  * 4. Redistributions of any form whatsoever must retain the following
33
+  *    acknowledgment:
34
+@@ -101,8 +101,6 @@ typedef unsigned short uint32;
35
+ 
36
+ /*****************************  Common Section  *****************************/
37
+ 
38
+-static const char plugin_id[] = "$Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $";
39
+-
40
+ /* Size limit of cipher block size */
41
+ #define SRP_MAXBLOCKSIZE 16
42
+ /* Size limit of SRP buffer */
43
+@@ -216,22 +214,22 @@ typedef struct srp_options_s {
44
+ typedef struct context {
45
+     int state;
46
+     
47
+-    BIGNUM N;			/* safe prime modulus */
48
+-    BIGNUM g;			/* generator */
49
++    BIGNUM *N;			/* safe prime modulus */
50
++    BIGNUM *g;			/* generator */
51
+     
52
+-    BIGNUM v;			/* password verifier */
53
++    BIGNUM *v;			/* password verifier */
54
+     
55
+-    BIGNUM b;			/* server private key */
56
+-    BIGNUM B;			/* server public key */
57
++    BIGNUM *b;			/* server private key */
58
++    BIGNUM *B;			/* server public key */
59
+     
60
+-    BIGNUM a;			/* client private key */
61
+-    BIGNUM A;			/* client public key */
62
++    BIGNUM *a;			/* client private key */
63
++    BIGNUM *A;			/* client public key */
64
+     
65
+-    char K[EVP_MAX_MD_SIZE];	/* shared context key */
66
+-    int Klen;
67
++    unsigned char K[EVP_MAX_MD_SIZE];	/* shared context key */
68
++    unsigned int Klen;
69
+     
70
+-    char M1[EVP_MAX_MD_SIZE];	/* client evidence */
71
+-    int M1len;
72
++    unsigned char M1[EVP_MAX_MD_SIZE];	/* client evidence */
73
++    unsigned int M1len;
74
+     
75
+     char *authid;		/* authentication id (server) */
76
+     char *userid;		/* authorization id (server) */
77
+@@ -242,7 +240,7 @@ typedef struct context {
78
+     char *server_options;
79
+     
80
+     srp_options_t client_opts;	/* cache between client steps */
81
+-    char cIV[SRP_MAXBLOCKSIZE];	/* cache between client steps */
82
++    unsigned char cIV[SRP_MAXBLOCKSIZE];	/* cache between client steps */
83
+     
84
+     char *salt;			/* password salt */
85
+     int saltlen;
86
+@@ -259,12 +257,12 @@ typedef struct context {
87
+     /* Layer foo */
88
+     unsigned layer;		/* bitmask of enabled layers */
89
+     const EVP_MD *hmac_md;	/* HMAC for integrity */
90
+-    HMAC_CTX hmac_send_ctx;
91
+-    HMAC_CTX hmac_recv_ctx;
92
++    HMAC_CTX *hmac_send_ctx;
93
++    HMAC_CTX *hmac_recv_ctx;
94
+ 
95
+     const EVP_CIPHER *cipher;	/* cipher for confidentiality */
96
+-    EVP_CIPHER_CTX cipher_enc_ctx;
97
+-    EVP_CIPHER_CTX cipher_dec_ctx;
98
++    EVP_CIPHER_CTX *cipher_enc_ctx;
99
++    EVP_CIPHER_CTX *cipher_dec_ctx;
100
+     
101
+     /* replay detection sequence numbers */
102
+     int seqnum_out;
103
+@@ -279,6 +277,52 @@ typedef struct context {
104
+     
105
+ } context_t;
106
+ 
107
++static void *OPENSSL_zalloc(size_t num)
108
++{
109
++    void *ret = OPENSSL_malloc(num);
110
++
111
++    if (ret != NULL)
112
++        memset(ret, 0, num);
113
++    return ret;
114
++}
115
++
116
++HMAC_CTX *HMAC_CTX_new(void)
117
++{
118
++    HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
119
++    if (ctx != NULL) {
120
++        if (!HMAC_CTX_reset(ctx)) {
121
++            HMAC_CTX_free(ctx);
122
++            return NULL;
123
++        }
124
++    }
125
++    return ctx;
126
++}
127
++
128
++void HMAC_CTX_free(HMAC_CTX *ctx)
129
++{
130
++    if (ctx != NULL) {
131
++        HMAC_CTX_cleanup(ctx);
132
++        OPENSSL_free(ctx);
133
++    }
134
++}
135
++
136
++int HMAC_CTX_reset(HMAC_CTX *ctx)
137
++{
138
++    HMAC_CTX_init(ctx);
139
++    return 1;
140
++}
141
++
142
++void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
143
++{
144
++        EVP_MD_CTX_cleanup(ctx);
145
++            OPENSSL_free(ctx);
146
++}
147
++
148
++EVP_MD_CTX *EVP_MD_CTX_new(void)
149
++{
150
++    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
151
++}
152
++
153
+ static int srp_encode(void *context,
154
+ 		      const struct iovec *invec,
155
+ 		      unsigned numiov,
156
+@@ -317,12 +361,12 @@ static int srp_encode(void *context,
157
+ 	inputlen = invec[i].iov_len;
158
+     
159
+ 	if (text->layer & BIT_CONFIDENTIALITY) {
160
+-	    unsigned enclen;
161
++	    int enclen;
162
+ 
163
+ 	    /* encrypt the data into the output buffer */
164
+-	    EVP_EncryptUpdate(&text->cipher_enc_ctx,
165
+-			      text->encode_buf + *outputlen, &enclen,
166
+-			      input, inputlen);
167
++	    EVP_EncryptUpdate(text->cipher_enc_ctx,
168
++			      (unsigned char *) text->encode_buf + *outputlen,
169
++                              &enclen, (unsigned char *) input, inputlen);
170
+ 	    *outputlen += enclen;
171
+ 
172
+ 	    /* switch the input to the encrypted data */
173
+@@ -337,11 +381,12 @@ static int srp_encode(void *context,
174
+     }
175
+     
176
+     if (text->layer & BIT_CONFIDENTIALITY) {
177
+-	unsigned enclen;
178
++	int enclen;
179
+ 
180
+ 	/* encrypt the last block of data into the output buffer */
181
+-	EVP_EncryptFinal(&text->cipher_enc_ctx,
182
+-			 text->encode_buf + *outputlen, &enclen);
183
++	EVP_EncryptFinal(text->cipher_enc_ctx,
184
++			 (unsigned char *) text->encode_buf + *outputlen,
185
++                         &enclen);
186
+ 	*outputlen += enclen;
187
+     }
188
+ 
189
+@@ -349,18 +394,20 @@ static int srp_encode(void *context,
190
+ 	unsigned hashlen;
191
+ 
192
+ 	/* hash the content */
193
+-	HMAC_Update(&text->hmac_send_ctx, text->encode_buf+4, *outputlen-4);
194
++	HMAC_Update(text->hmac_send_ctx,
195
++                    (unsigned char *) text->encode_buf+4, *outputlen-4);
196
+ 	
197
+ 	if (text->layer & BIT_REPLAY_DETECTION) {
198
+ 	    /* hash the sequence number */
199
+ 	    tmpnum = htonl(text->seqnum_out);
200
+-	    HMAC_Update(&text->hmac_send_ctx, (char *) &tmpnum, 4);
201
++	    HMAC_Update(text->hmac_send_ctx, (unsigned char *) &tmpnum, 4);
202
+ 	    
203
+ 	    text->seqnum_out++;
204
+ 	}
205
+ 
206
+ 	/* append the HMAC into the output buffer */
207
+-	HMAC_Final(&text->hmac_send_ctx, text->encode_buf + *outputlen,
208
++	HMAC_Final(text->hmac_send_ctx,
209
++                   (unsigned char *) text->encode_buf + *outputlen,
210
+ 		   &hashlen);
211
+ 	*outputlen += hashlen;
212
+     }
213
+@@ -387,8 +434,8 @@ static int srp_decode_packet(void *conte
214
+ 
215
+     if (text->layer & BIT_INTEGRITY) {
216
+ 	const char *hash;
217
+-	char myhash[EVP_MAX_MD_SIZE];
218
+-	unsigned hashlen, myhashlen, i;
219
++	unsigned char myhash[EVP_MAX_MD_SIZE];
220
++	unsigned hashlen;
221
+ 	unsigned long tmpnum;
222
+ 
223
+ 	hashlen = EVP_MD_size(text->hmac_md);
224
+@@ -405,25 +452,23 @@ static int srp_decode_packet(void *conte
225
+ 	hash = input + inputlen;
226
+ 
227
+ 	/* create our own hash from the input */
228
+-	HMAC_Update(&text->hmac_recv_ctx, input, inputlen);
229
++	HMAC_Update(text->hmac_recv_ctx, (unsigned char *) input, inputlen);
230
+ 	    
231
+ 	if (text->layer & BIT_REPLAY_DETECTION) {
232
+ 	    /* hash the sequence number */
233
+ 	    tmpnum = htonl(text->seqnum_in);
234
+-	    HMAC_Update(&text->hmac_recv_ctx, (char *) &tmpnum, 4);
235
++	    HMAC_Update(text->hmac_recv_ctx, (unsigned char *) &tmpnum, 4);
236
+ 		
237
+ 	    text->seqnum_in++;
238
+ 	}
239
+ 	    
240
+-	HMAC_Final(&text->hmac_recv_ctx, myhash, &myhashlen);
241
++	HMAC_Final(text->hmac_recv_ctx, myhash, &hashlen);
242
+ 
243
+ 	/* compare hashes */
244
+-	for (i = 0; i < hashlen; i++) {
245
+-	    if ((myhashlen != hashlen) || (myhash[i] != hash[i])) {
246
+-		SETERROR(text->utils, "Hash is incorrect\n");
247
+-		return SASL_BADMAC;
248
+-	    }
249
+-	}
250
++        if (memcmp(hash, myhash, hashlen)) {
251
++            SETERROR(text->utils, "Hash is incorrect\n");
252
++            return SASL_BADMAC;
253
++        }
254
+     }
255
+ 	
256
+     ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf),
257
+@@ -432,16 +477,17 @@ static int srp_decode_packet(void *conte
258
+     if (ret != SASL_OK) return ret;
259
+ 	
260
+     if (text->layer & BIT_CONFIDENTIALITY) {
261
+-	unsigned declen;
262
++	int declen;
263
+ 
264
+ 	/* decrypt the data into the output buffer */
265
+-	EVP_DecryptUpdate(&text->cipher_dec_ctx,
266
+-			  text->decode_pkt_buf, &declen,
267
+-			  (char *) input, inputlen);
268
++	EVP_DecryptUpdate(text->cipher_dec_ctx,
269
++			  (unsigned char *) text->decode_pkt_buf, &declen,
270
++			  (unsigned char *) input, inputlen);
271
+ 	*outputlen = declen;
272
+ 	    
273
+-	EVP_DecryptFinal(&text->cipher_dec_ctx,
274
+-			 text->decode_pkt_buf + declen, &declen);
275
++	EVP_DecryptFinal(text->cipher_dec_ctx,
276
++			 (unsigned char *) text->decode_pkt_buf + declen,
277
++                         &declen);
278
+ 	*outputlen += declen;
279
+     } else {
280
+ 	/* copy the raw input to the output */
281
+@@ -474,7 +520,8 @@ static int srp_decode(void *context,
282
+ /*
283
+  * Convert a big integer to it's byte representation
284
+  */
285
+-static int BigIntToBytes(BIGNUM *num, char *out, int maxoutlen, int *outlen)
286
++static int BigIntToBytes(BIGNUM *num, unsigned char *out, int maxoutlen,
287
++                         unsigned int *outlen)
288
+ {
289
+     int len;
290
+     
291
+@@ -504,12 +551,12 @@ static int BigIntCmpWord(BIGNUM *a, BN_U
292
+ /*
293
+  * Generate a random big integer.
294
+  */
295
+-static void GetRandBigInt(BIGNUM *out)
296
++static void GetRandBigInt(BIGNUM **out)
297
+ {
298
+-    BN_init(out);
299
++    *out = BN_new();
300
+     
301
+     /* xxx likely should use sasl random funcs */
302
+-    BN_rand(out, SRP_MAXBLOCKSIZE*8, 0, 0);
303
++    BN_rand(*out, SRP_MAXBLOCKSIZE*8, 0, 0);
304
+ }
305
+ 
306
+ #define MAX_BUFFER_LEN 2147483643
307
+@@ -624,7 +671,8 @@ static int MakeBuffer(const sasl_utils_t
308
+ 	case 'm':
309
+ 	    /* MPI */
310
+ 	    mpi = va_arg(ap, BIGNUM *);
311
+-	    r = BigIntToBytes(mpi, out+2, BN_num_bytes(mpi), &len);
312
++	    r = BigIntToBytes(mpi, (unsigned char *) out+2,
313
++                              BN_num_bytes(mpi), (unsigned *) &len);
314
+ 	    if (r) goto done;
315
+ 	    ns = htons(len);
316
+ 	    memcpy(out, &ns, 2);	/* add 2 byte len (network order) */
317
+@@ -695,7 +743,7 @@ static int UnBuffer(const sasl_utils_t *
318
+     va_list ap;
319
+     char *p;
320
+     int r = SASL_OK, noalloc;
321
+-    BIGNUM *mpi;
322
++    BIGNUM **mpi;
323
+     char **os, **str;
324
+     uint32 *u;
325
+     unsigned short ns;
326
+@@ -757,9 +805,12 @@ static int UnBuffer(const sasl_utils_t *
327
+ 		goto done;
328
+ 	    }
329
+ 	    
330
+-	    mpi = va_arg(ap, BIGNUM *);
331
+-	    BN_init(mpi);
332
+-	    BN_bin2bn(buf, len, mpi);
333
++	    mpi = va_arg(ap, BIGNUM **);
334
++            if (mpi) {
335
++                if (!*mpi) *mpi = BN_new();
336
++                else BN_clear(*mpi);
337
++                BN_bin2bn((unsigned char *) buf, len, *mpi);
338
++            }
339
+ 	    break;
340
+ 
341
+ 	case 'o':
342
+@@ -883,16 +934,17 @@ static int UnBuffer(const sasl_utils_t *
343
+ /*
344
+  * Apply the hash function to the data specifed by the fmt string.
345
+  */
346
+-static int MakeHash(const EVP_MD *md, unsigned char hash[], int *hashlen,
347
++static int MakeHash(const EVP_MD *md,
348
++                    unsigned char hash[], unsigned int *hashlen,
349
+ 		    const char *fmt, ...)
350
+ {
351
+     va_list ap;
352
+     char *p, buf[4096], *in;
353
+-    int inlen;
354
+-    EVP_MD_CTX mdctx;
355
++    unsigned int inlen;
356
++    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
357
+     int r = 0, hflag;
358
+ 
359
+-    EVP_DigestInit(&mdctx, md);
360
++    EVP_DigestInit(mdctx, md);
361
+ 
362
+     va_start(ap, fmt);
363
+     for (p = (char *) fmt; *p; p++) {
364
+@@ -910,7 +962,7 @@ static int MakeHash(const EVP_MD *md, un
365
+ 		BIGNUM *mval = va_arg(ap, BIGNUM *);
366
+ 
367
+ 		in = buf;
368
+-		r = BigIntToBytes(mval, buf, sizeof(buf)-1, &inlen);
369
++		r = BigIntToBytes(mval, (unsigned char *) buf, sizeof(buf)-1, &inlen);
370
+ 		if (r) goto done;
371
+ 		break;
372
+ 	    }
373
+@@ -947,47 +999,52 @@ static int MakeHash(const EVP_MD *md, un
374
+ 
375
+ 	if (hflag) {
376
+ 	    /* hash data separately before adding to current hash */
377
+-	    EVP_MD_CTX tmpctx;
378
++	    EVP_MD_CTX *tmpctx = EVP_MD_CTX_new();
379
+ 
380
+-	    EVP_DigestInit(&tmpctx, md);
381
+-	    EVP_DigestUpdate(&tmpctx, in, inlen);
382
+-	    EVP_DigestFinal(&tmpctx, buf, &inlen);
383
++	    EVP_DigestInit(tmpctx, md);
384
++	    EVP_DigestUpdate(tmpctx, in, inlen);
385
++	    EVP_DigestFinal(tmpctx, (unsigned char *) buf, &inlen);
386
++            EVP_MD_CTX_free(tmpctx);
387
+ 	    in = buf;
388
+ 	}
389
+ 
390
+-	EVP_DigestUpdate(&mdctx, in, inlen);
391
++	EVP_DigestUpdate(mdctx, in, inlen);
392
+     }
393
+   done:
394
+     va_end(ap);
395
+ 
396
+-    EVP_DigestFinal(&mdctx, hash, hashlen);
397
++    EVP_DigestFinal(mdctx, hash, hashlen);
398
++    EVP_MD_CTX_free(mdctx);
399
+ 
400
+     return r;
401
+ }
402
+ 
403
+ static int CalculateX(context_t *text, const char *salt, int saltlen, 
404
+-		      const char *user, const char *pass, int passlen, 
405
+-		      BIGNUM *x)
406
++		      const char *user, const unsigned char *pass, int passlen, 
407
++		      BIGNUM **x)
408
+ {
409
+-    char hash[EVP_MAX_MD_SIZE];
410
+-    int hashlen;
411
++    unsigned char hash[EVP_MAX_MD_SIZE];
412
++    unsigned int hashlen;
413
+     
414
+     /* x = H(salt | H(user | ':' | pass)) */
415
+     MakeHash(text->md, hash, &hashlen, "%s:%o", user, passlen, pass);
416
+     MakeHash(text->md, hash, &hashlen, "%o%o", saltlen, salt, hashlen, hash);
417
+     
418
+-    BN_init(x);
419
+-    BN_bin2bn(hash, hashlen, x);
420
++    *x = BN_new();
421
++    BN_bin2bn(hash, hashlen, *x);
422
+     
423
+     return SASL_OK;
424
+ }
425
+ 
426
+ static int CalculateM1(context_t *text, BIGNUM *N, BIGNUM *g,
427
+ 		       char *U, char *salt, int saltlen,
428
+-		       BIGNUM *A, BIGNUM *B, char *K, int Klen,
429
+-		       char *I, char *L, char *M1, int *M1len)
430
++		       BIGNUM *A, BIGNUM *B,
431
++                       unsigned char *K, unsigned int Klen,
432
++		       char *I, char *L,
433
++                       unsigned char *M1, unsigned int *M1len)
434
+ {
435
+-    int r, i, len;
436
++    int r;
437
++    unsigned int i, len;
438
+     unsigned char Nhash[EVP_MAX_MD_SIZE];
439
+     unsigned char ghash[EVP_MAX_MD_SIZE];
440
+     unsigned char Ng[EVP_MAX_MD_SIZE];
441
+@@ -1010,9 +1067,10 @@ static int CalculateM1(context_t *text,
442
+ }
443
+ 
444
+ static int CalculateM2(context_t *text, BIGNUM *A,
445
+-		       char *M1, int M1len, char *K, int Klen,
446
++		       unsigned char *M1, unsigned int M1len,
447
++                       unsigned char *K, unsigned int Klen,
448
+ 		       char *I, char *o, char *sid, uint32 ttl,
449
+-		       char *M2, int *M2len)
450
++		       unsigned char *M2, unsigned int *M2len)
451
+ {
452
+     int r;
453
+     
454
+@@ -1386,7 +1444,8 @@ static int SetMDA(srp_options_t *opts, c
455
+  * Setup the selected security layer.
456
+  */
457
+ static int LayerInit(srp_options_t *opts, context_t *text,
458
+-		     sasl_out_params_t *oparams, char *enc_IV, char *dec_IV,
459
++		     sasl_out_params_t *oparams,
460
++                     unsigned char *enc_IV, unsigned char *dec_IV,
461
+ 		     unsigned maxbufsize)
462
+ {
463
+     layer_option_t *opt;
464
+@@ -1431,8 +1490,10 @@ static int LayerInit(srp_options_t *opts
465
+ 
466
+ 	/* Initialize the HMACs */
467
+ 	text->hmac_md = EVP_get_digestbyname(opt->evp_name);
468
+-	HMAC_Init(&text->hmac_send_ctx, text->K, text->Klen, text->hmac_md);
469
+-	HMAC_Init(&text->hmac_recv_ctx, text->K, text->Klen, text->hmac_md);
470
++        text->hmac_send_ctx = HMAC_CTX_new();
471
++	HMAC_Init_ex(text->hmac_send_ctx, text->K, text->Klen, text->hmac_md, NULL);
472
++        text->hmac_recv_ctx = HMAC_CTX_new();
473
++	HMAC_Init_ex(text->hmac_recv_ctx, text->K, text->Klen, text->hmac_md, NULL);
474
+ 	
475
+ 	/* account for HMAC */
476
+ 	oparams->maxoutbuf -= EVP_MD_size(text->hmac_md);
477
+@@ -1456,11 +1517,13 @@ static int LayerInit(srp_options_t *opts
478
+ 	/* Initialize the ciphers */
479
+ 	text->cipher = EVP_get_cipherbyname(opt->evp_name);
480
+ 
481
+-	EVP_CIPHER_CTX_init(&text->cipher_enc_ctx);
482
+-	EVP_EncryptInit(&text->cipher_enc_ctx, text->cipher, text->K, enc_IV);
483
+-
484
+-	EVP_CIPHER_CTX_init(&text->cipher_dec_ctx);
485
+-	EVP_DecryptInit(&text->cipher_dec_ctx, text->cipher, text->K, dec_IV);
486
++        text->cipher_enc_ctx = EVP_CIPHER_CTX_new();
487
++	EVP_CIPHER_CTX_init(text->cipher_enc_ctx);
488
++	EVP_EncryptInit(text->cipher_enc_ctx, text->cipher, text->K, enc_IV);
489
++
490
++        text->cipher_dec_ctx = EVP_CIPHER_CTX_new();
491
++	EVP_CIPHER_CTX_init(text->cipher_dec_ctx);
492
++	EVP_DecryptInit(text->cipher_dec_ctx, text->cipher, text->K, dec_IV);
493
+     }
494
+     
495
+     return SASL_OK;
496
+@@ -1469,13 +1532,13 @@ static int LayerInit(srp_options_t *opts
497
+ static void LayerCleanup(context_t *text)
498
+ {
499
+     if (text->layer & BIT_INTEGRITY) {
500
+-	HMAC_cleanup(&text->hmac_send_ctx);
501
+-	HMAC_cleanup(&text->hmac_recv_ctx);
502
++	HMAC_CTX_free(text->hmac_send_ctx);
503
++	HMAC_CTX_free(text->hmac_recv_ctx);
504
+     }
505
+ 
506
+     if (text->layer & BIT_CONFIDENTIALITY) {
507
+-	EVP_CIPHER_CTX_cleanup(&text->cipher_enc_ctx);
508
+-	EVP_CIPHER_CTX_cleanup(&text->cipher_dec_ctx);
509
++	EVP_CIPHER_CTX_free(text->cipher_enc_ctx);
510
++	EVP_CIPHER_CTX_free(text->cipher_dec_ctx);
511
+     }
512
+ }
513
+     
514
+@@ -1490,13 +1553,13 @@ static void srp_common_mech_dispose(void
515
+     
516
+     if (!text) return;
517
+     
518
+-    BN_clear_free(&text->N);
519
+-    BN_clear_free(&text->g);
520
+-    BN_clear_free(&text->v);
521
+-    BN_clear_free(&text->b);
522
+-    BN_clear_free(&text->B);
523
+-    BN_clear_free(&text->a);
524
+-    BN_clear_free(&text->A);
525
++    BN_clear_free(text->N);
526
++    BN_clear_free(text->g);
527
++    BN_clear_free(text->v);
528
++    BN_clear_free(text->b);
529
++    BN_clear_free(text->B);
530
++    BN_clear_free(text->a);
531
++    BN_clear_free(text->A);
532
+     
533
+     if (text->authid)		utils->free(text->authid);
534
+     if (text->userid)		utils->free(text->userid);
535
+@@ -1534,16 +1597,16 @@ srp_common_mech_free(void *global_contex
536
+  *
537
+  * All arithmetic is done modulo N
538
+  */
539
+-static int generate_N_and_g(BIGNUM *N, BIGNUM *g)
540
++static int generate_N_and_g(BIGNUM **N, BIGNUM **g)
541
+ {
542
+     int result;
543
+-    
544
+-    BN_init(N);
545
+-    result = BN_hex2bn(&N, Ng_tab[NUM_Ng-1].N);
546
++
547
++    *N = BN_new();
548
++    result = BN_hex2bn(N, Ng_tab[NUM_Ng-1].N);
549
+     if (!result) return SASL_FAIL;
550
+     
551
+-    BN_init(g);
552
+-    BN_set_word(g, Ng_tab[NUM_Ng-1].g);
553
++    *g = BN_new();
554
++    BN_set_word(*g, Ng_tab[NUM_Ng-1].g);
555
+     
556
+     return SASL_OK;
557
+ }
558
+@@ -1551,10 +1614,10 @@ static int generate_N_and_g(BIGNUM *N, B
559
+ static int CalculateV(context_t *text,
560
+ 		      BIGNUM *N, BIGNUM *g,
561
+ 		      const char *user,
562
+-		      const char *pass, unsigned passlen,
563
+-		      BIGNUM *v, char **salt, int *saltlen)
564
++		      const unsigned char *pass, unsigned passlen,
565
++		      BIGNUM **v, char **salt, int *saltlen)
566
+ {
567
+-    BIGNUM x;
568
++    BIGNUM *x = NULL;
569
+     BN_CTX *ctx = BN_CTX_new();
570
+     int r;
571
+     
572
+@@ -1572,40 +1635,41 @@ static int CalculateV(context_t *text,
573
+     }
574
+     
575
+     /* v = g^x % N */
576
+-    BN_init(v);
577
+-    BN_mod_exp(v, g, &x, N, ctx);
578
++    *v = BN_new();
579
++    BN_mod_exp(*v, g, x, N, ctx);
580
+     
581
+     BN_CTX_free(ctx);
582
+-    BN_clear_free(&x);
583
++    BN_clear_free(x);
584
+     
585
+     return r;   
586
+ }
587
+ 
588
+ static int CalculateB(context_t *text  __attribute__((unused)),
589
+-		      BIGNUM *v, BIGNUM *N, BIGNUM *g, BIGNUM *b, BIGNUM *B)
590
++		      BIGNUM *v, BIGNUM *N, BIGNUM *g, BIGNUM **b, BIGNUM **B)
591
+ {
592
+-    BIGNUM v3;
593
++    BIGNUM *v3 = BN_new();
594
+     BN_CTX *ctx = BN_CTX_new();
595
+     
596
+     /* Generate b */
597
+     GetRandBigInt(b);
598
+ 	
599
+     /* Per [SRP]: make sure b > log[g](N) -- g is always 2 */
600
+-    BN_add_word(b, BN_num_bits(N));
601
++    BN_add_word(*b, BN_num_bits(N));
602
+ 	
603
+     /* B = (3v + g^b) % N */
604
+-    BN_init(&v3);
605
+-    BN_set_word(&v3, 3);
606
+-    BN_mod_mul(&v3, &v3, v, N, ctx);
607
+-    BN_init(B);
608
+-    BN_mod_exp(B, g, b, N, ctx);
609
++    BN_set_word(v3, 3);
610
++    BN_mod_mul(v3, v3, v, N, ctx);
611
++
612
++    *B = BN_new();
613
++    BN_mod_exp(*B, g, *b, N, ctx);
614
+ #if OPENSSL_VERSION_NUMBER >= 0x00907000L
615
+-    BN_mod_add(B, B, &v3, N, ctx);
616
++    BN_mod_add(*B, *B, v3, N, ctx);
617
+ #else
618
+-    BN_add(B, B, &v3);
619
+-    BN_mod(B, B, N, ctx);
620
++    BN_add(*B, *B, v3);
621
++    BN_mod(*B, *B, N, ctx);
622
+ #endif
623
+ 
624
++    BN_clear_free(v3);
625
+     BN_CTX_free(ctx);
626
+     
627
+     return SASL_OK;
628
+@@ -1613,13 +1677,13 @@ static int CalculateB(context_t *text  _
629
+ 	
630
+ static int ServerCalculateK(context_t *text, BIGNUM *v,
631
+ 			    BIGNUM *N, BIGNUM *A, BIGNUM *b, BIGNUM *B,
632
+-			    char *K, int *Klen)
633
++			    unsigned char *K, unsigned int *Klen)
634
+ {
635
+     unsigned char hash[EVP_MAX_MD_SIZE];
636
+-    int hashlen;
637
+-    BIGNUM u;
638
+-    BIGNUM base;
639
+-    BIGNUM S;
640
++    unsigned int hashlen;
641
++    BIGNUM *u = BN_new();
642
++    BIGNUM *base = BN_new();
643
++    BIGNUM *S = BN_new();
644
+     BN_CTX *ctx = BN_CTX_new();
645
+     int r;
646
+     
647
+@@ -1627,50 +1691,47 @@ static int ServerCalculateK(context_t *t
648
+     r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B);
649
+     if (r) return r;
650
+ 	
651
+-    BN_init(&u);
652
+-    BN_bin2bn(hash, hashlen, &u);
653
++    BN_bin2bn(hash, hashlen, u);
654
+ 	
655
+     /* S = (Av^u) ^ b % N */
656
+-    BN_init(&base);
657
+-    BN_mod_exp(&base, v, &u, N, ctx);
658
+-    BN_mod_mul(&base, &base, A, N, ctx);
659
++    BN_mod_exp(base, v, u, N, ctx);
660
++    BN_mod_mul(base, base, A, N, ctx);
661
+     
662
+-    BN_init(&S);
663
+-    BN_mod_exp(&S, &base, b, N, ctx);
664
++    BN_mod_exp(S, base, b, N, ctx);
665
+     
666
+     /* per Tom Wu: make sure Av^u != 1 (mod N) */
667
+-    if (BN_is_one(&base)) {
668
++    if (BN_is_one(base)) {
669
+ 	SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n");
670
+ 	r = SASL_BADPROT;
671
+ 	goto err;
672
+     }
673
+     
674
+     /* per Tom Wu: make sure Av^u != -1 (mod N) */
675
+-    BN_add_word(&base, 1);
676
+-    if (BN_cmp(&S, N) == 0) {
677
++    BN_add_word(base, 1);
678
++    if (BN_cmp(S, N) == 0) {
679
+ 	SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n");
680
+ 	r = SASL_BADPROT;
681
+ 	goto err;
682
+     }
683
+     
684
+     /* K = H(S) */
685
+-    r = MakeHash(text->md, K, Klen, "%m", &S);
686
++    r = MakeHash(text->md, K, Klen, "%m", S);
687
+     if (r) goto err;
688
+     
689
+     r = SASL_OK;
690
+     
691
+   err:
692
+     BN_CTX_free(ctx);
693
+-    BN_clear_free(&u);
694
+-    BN_clear_free(&base);
695
+-    BN_clear_free(&S);
696
++    BN_clear_free(u);
697
++    BN_clear_free(base);
698
++    BN_clear_free(S);
699
+     
700
+     return r;
701
+ }
702
+ 
703
+ static int ParseUserSecret(const sasl_utils_t *utils,
704
+ 			   char *secret, size_t seclen,
705
+-			   char **mda, BIGNUM *v, char **salt, int *saltlen)
706
++			   char **mda, BIGNUM **v, char **salt, int *saltlen)
707
+ {
708
+     int r;
709
+     
710
+@@ -1678,7 +1739,7 @@ static int ParseUserSecret(const sasl_ut
711
+      *
712
+      *  { utf8(mda) mpi(v) os(salt) }  (base64 encoded)
713
+      */
714
+-    r = utils->decode64(secret, seclen, secret, seclen, &seclen);
715
++    r = utils->decode64(secret, seclen, secret, seclen, (unsigned *) &seclen);
716
+ 
717
+     if (!r)
718
+ 	r = UnBuffer(utils, secret, seclen, "%s%m%o", mda, v, saltlen, salt);
719
+@@ -1919,8 +1980,8 @@ static int srp_server_mech_step1(context
720
+ 	    goto cleanup;
721
+ 	}
722
+ 	
723
+-	result = CalculateV(text, &text->N, &text->g, text->authid,
724
+-			    auxprop_values[1].values[0], len,
725
++	result = CalculateV(text, text->N, text->g, text->authid,
726
++			    (unsigned char *) auxprop_values[1].values[0], len,
727
+ 			    &text->v, &text->salt, &text->saltlen);
728
+ 	if (result) {
729
+ 	    params->utils->seterror(params->utils->conn, 0, 
730
+@@ -1938,8 +1999,7 @@ static int srp_server_mech_step1(context
731
+     params->utils->prop_erase(params->propctx, password_request[1]);
732
+     
733
+     /* Calculate B */
734
+-    result = CalculateB(text, &text->v, &text->N, &text->g,
735
+-			&text->b, &text->B);
736
++    result = CalculateB(text, text->v, text->N, text->g, &text->b, &text->B);
737
+     if (result) {
738
+ 	params->utils->seterror(params->utils->conn, 0, 
739
+ 				"Error calculating B");
740
+@@ -1967,8 +2027,8 @@ static int srp_server_mech_step1(context
741
+      */
742
+     result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
743
+ 			serveroutlen, "%c%m%m%o%m%s",
744
+-			0x00, &text->N, &text->g, text->saltlen, text->salt,
745
+-			&text->B, text->server_options);
746
++			0x00, text->N, text->g, text->saltlen, text->salt,
747
++			text->B, text->server_options);
748
+     if (result) {
749
+ 	params->utils->seterror(params->utils->conn, 0, 
750
+ 				"Error creating SRP buffer from data in step 1");
751
+@@ -1997,15 +2057,15 @@ static int srp_server_mech_step2(context
752
+ 			sasl_out_params_t *oparams)
753
+ {
754
+     int result;    
755
+-    char *M1 = NULL, *cIV = NULL; /* don't free */
756
+-    int M1len, cIVlen;
757
++    unsigned char *M1 = NULL, *cIV = NULL; /* don't free */
758
++    unsigned int M1len, cIVlen;
759
+     srp_options_t client_opts;
760
+-    char myM1[EVP_MAX_MD_SIZE];
761
+-    int myM1len;
762
+-    int i;
763
+-    char M2[EVP_MAX_MD_SIZE];
764
+-    int M2len;
765
+-    char sIV[SRP_MAXBLOCKSIZE];
766
++    unsigned char myM1[EVP_MAX_MD_SIZE];
767
++    unsigned int myM1len;
768
++    unsigned int i;
769
++    unsigned char M2[EVP_MAX_MD_SIZE];
770
++    unsigned int M2len;
771
++    unsigned char sIV[SRP_MAXBLOCKSIZE];
772
+     
773
+     /* Expect:
774
+      *
775
+@@ -2027,7 +2087,7 @@ static int srp_server_mech_step2(context
776
+     }
777
+     
778
+     /* Per [SRP]: reject A <= 0 */
779
+-    if (BigIntCmpWord(&text->A, 0) <= 0) {
780
++    if (BigIntCmpWord(text->A, 0) <= 0) {
781
+ 	SETERROR(params->utils, "Illegal value for 'A'\n");
782
+ 	result = SASL_BADPROT;
783
+ 	goto cleanup;
784
+@@ -2058,8 +2118,8 @@ static int srp_server_mech_step2(context
785
+     }
786
+ 
787
+     /* Calculate K */
788
+-    result = ServerCalculateK(text, &text->v, &text->N, &text->A,
789
+-			      &text->b, &text->B, text->K, &text->Klen);
790
++    result = ServerCalculateK(text, text->v, text->N, text->A,
791
++			      text->b, text->B, text->K, &text->Klen);
792
+     if (result) {
793
+ 	params->utils->seterror(params->utils->conn, 0, 
794
+ 				"Error calculating K");
795
+@@ -2067,8 +2127,8 @@ static int srp_server_mech_step2(context
796
+     }
797
+     
798
+     /* See if M1 is correct */
799
+-    result = CalculateM1(text, &text->N, &text->g, text->authid,
800
+-			 text->salt, text->saltlen, &text->A, &text->B,
801
++    result = CalculateM1(text, text->N, text->g, text->authid,
802
++			 text->salt, text->saltlen, text->A, text->B,
803
+ 			 text->K, text->Klen, text->userid,
804
+ 			 text->server_options, myM1, &myM1len);
805
+     if (result) {
806
+@@ -2095,7 +2155,7 @@ static int srp_server_mech_step2(context
807
+     }
808
+     
809
+     /* calculate M2 to send */
810
+-    result = CalculateM2(text, &text->A, M1, M1len, text->K, text->Klen,
811
++    result = CalculateM2(text, text->A, M1, M1len, text->K, text->Klen,
812
+ 			 text->userid, text->client_options, "", 0,
813
+ 			 M2, &M2len);
814
+     if (result) {
815
+@@ -2105,7 +2165,7 @@ static int srp_server_mech_step2(context
816
+     }
817
+     
818
+     /* Create sIV (server initial vector) */
819
+-    text->utils->rand(text->utils->rpool, sIV, sizeof(sIV));
820
++    text->utils->rand(text->utils->rpool, (char *) sIV, sizeof(sIV));
821
+     
822
+     /*
823
+      * Send out:
824
+@@ -2230,20 +2290,20 @@ static int srp_setpass(void *glob_contex
825
+     r = _plug_make_fulluser(sparams->utils, &user, user_only, realm);
826
+ 
827
+     if (r) {
828
+-	goto end;
829
++	goto cleanup;
830
+     }
831
+ 
832
+     if ((flags & SASL_SET_DISABLE) || pass == NULL) {
833
+ 	sec = NULL;
834
+     } else {
835
+-	context_t *text;
836
+-	BIGNUM N;
837
+-	BIGNUM g;
838
+-	BIGNUM v;
839
++	context_t *text = NULL;
840
++	BIGNUM *N = NULL;
841
++	BIGNUM *g = NULL;
842
++	BIGNUM *v = NULL;
843
+ 	char *salt;
844
+ 	int saltlen;
845
+ 	char *buffer = NULL;
846
+-	int bufferlen, alloclen, encodelen;
847
++	unsigned int bufferlen, alloclen, encodelen;
848
+ 	
849
+ 	text = sparams->utils->malloc(sizeof(context_t));
850
+ 	if (text == NULL) {
851
+@@ -2264,7 +2324,8 @@ static int srp_setpass(void *glob_contex
852
+ 	}
853
+ 
854
+ 	/* user is a full username here */
855
+-	r = CalculateV(text, &N, &g, user, pass, passlen, &v, &salt, &saltlen);
856
++	r = CalculateV(text, N, g, user,
857
++                       (unsigned char *) pass, passlen, &v, &salt, &saltlen);
858
+ 	if (r) {
859
+ 	    sparams->utils->seterror(sparams->utils->conn, 0, 
860
+ 				     "Error calculating v");
861
+@@ -2296,16 +2357,16 @@ static int srp_setpass(void *glob_contex
862
+ 	    r = SASL_NOMEM;
863
+ 	    goto end;
864
+ 	}
865
+-	sparams->utils->encode64(buffer, bufferlen, sec->data, alloclen,
866
++	sparams->utils->encode64(buffer, bufferlen, (char *) sec->data, alloclen,
867
+ 				 &encodelen);
868
+ 	sec->len = encodelen;
869
+ 	
870
+ 	/* Clean everything up */
871
+       end:
872
+ 	if (buffer) sparams->utils->free((void *) buffer);
873
+-	BN_clear_free(&N);
874
+-	BN_clear_free(&g);
875
+-	BN_clear_free(&v);
876
++	BN_clear_free(N);
877
++	BN_clear_free(g);
878
++	BN_clear_free(v);
879
+ 	sparams->utils->free(text);
880
+ 	
881
+ 	if (r) return r;
882
+@@ -2319,7 +2380,7 @@ static int srp_setpass(void *glob_contex
883
+ 	r = sparams->utils->prop_request(propctx, store_request);
884
+     if (!r)
885
+ 	r = sparams->utils->prop_set(propctx, "cmusaslsecretSRP",
886
+-				     (sec ? sec->data : NULL),
887
++				     (char *) (sec ? sec->data : NULL),
888
+ 				     (sec ? sec->len : 0));
889
+     if (!r)
890
+ 	r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user);
891
+@@ -2475,7 +2536,7 @@ static int check_N_and_g(const sasl_util
892
+ }
893
+ 
894
+ static int CalculateA(context_t *text  __attribute__((unused)),
895
+-		      BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A)
896
++		      BIGNUM *N, BIGNUM *g, BIGNUM **a, BIGNUM **A)
897
+ {
898
+     BN_CTX *ctx = BN_CTX_new();
899
+     
900
+@@ -2483,11 +2544,11 @@ static int CalculateA(context_t *text  _
901
+     GetRandBigInt(a);
902
+ 	
903
+     /* Per [SRP]: make sure a > log[g](N) -- g is always 2 */
904
+-    BN_add_word(a, BN_num_bits(N));
905
++    BN_add_word(*a, BN_num_bits(N));
906
+ 	
907
+     /* A = g^a % N */
908
+-    BN_init(A);
909
+-    BN_mod_exp(A, g, a, N, ctx);
910
++    *A = BN_new();
911
++    BN_mod_exp(*A, g, *a, N, ctx);
912
+ 
913
+     BN_CTX_free(ctx);
914
+     
915
+@@ -2495,30 +2556,29 @@ static int CalculateA(context_t *text  _
916
+ }
917
+ 	
918
+ static int ClientCalculateK(context_t *text, char *salt, int saltlen,
919
+-			    char *user, char *pass, int passlen,
920
++			    char *user, unsigned char *pass, int passlen,
921
+ 			    BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A,
922
+-			    BIGNUM *B, char *K, int *Klen)
923
++			    BIGNUM *B, unsigned char *K, unsigned int *Klen)
924
+ {
925
+     int r;
926
+     unsigned char hash[EVP_MAX_MD_SIZE];
927
+-    int hashlen;
928
+-    BIGNUM x;
929
+-    BIGNUM u;
930
+-    BIGNUM aux;
931
+-    BIGNUM gx;
932
+-    BIGNUM gx3;
933
+-    BIGNUM base;
934
+-    BIGNUM S;
935
++    unsigned int hashlen;
936
++    BIGNUM *x = NULL;
937
++    BIGNUM *u = BN_new();
938
++    BIGNUM *aux = BN_new();
939
++    BIGNUM *gx = BN_new();
940
++    BIGNUM *gx3 = BN_new();
941
++    BIGNUM *base = BN_new();
942
++    BIGNUM *S = BN_new();
943
+     BN_CTX *ctx = BN_CTX_new();
944
+     
945
+     /* u = H(A | B) */
946
+     r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B);
947
+     if (r) goto err;
948
+-    BN_init(&u);
949
+-    BN_bin2bn(hash, hashlen, &u);
950
++    BN_bin2bn(hash, hashlen, u);
951
+     
952
+     /* per Tom Wu: make sure u != 0 */
953
+-    if (BN_is_zero(&u)) {
954
++    if (BN_is_zero(u)) {
955
+ 	SETERROR(text->utils, "SRP: Illegal value for 'u'\n");
956
+ 	r = SASL_BADPROT;
957
+ 	goto err;
958
+@@ -2530,48 +2590,43 @@ static int ClientCalculateK(context_t *t
959
+     if (r) return r;
960
+     
961
+     /* a + ux */
962
+-    BN_init(&aux);
963
+-    BN_mul(&aux, &u, &x, ctx);
964
+-    BN_add(&aux, &aux, a);
965
++    BN_mul(aux, u, x, ctx);
966
++    BN_add(aux, aux, a);
967
+     
968
+     /* gx3 = 3(g^x) % N */
969
+-    BN_init(&gx);
970
+-    BN_mod_exp(&gx, g, &x, N, ctx);
971
+-    BN_init(&gx3);
972
+-    BN_set_word(&gx3, 3);
973
+-    BN_mod_mul(&gx3, &gx3, &gx, N, ctx);
974
++    BN_mod_exp(gx, g, x, N, ctx);
975
++    BN_set_word(gx3, 3);
976
++    BN_mod_mul(gx3, gx3, gx, N, ctx);
977
+     
978
+     /* base = (B - 3(g^x)) % N */
979
+-    BN_init(&base);
980
+ #if OPENSSL_VERSION_NUMBER >= 0x00907000L
981
+-    BN_mod_sub(&base, B, &gx3, N, ctx);
982
++    BN_mod_sub(base, B, gx3, N, ctx);
983
+ #else
984
+-    BN_sub(&base, B, &gx3);
985
+-    BN_mod(&base, &base, N, ctx);
986
+-    if (BigIntCmpWord(&base, 0) < 0) {
987
+-	BN_add(&base, &base, N);
988
++    BN_sub(base, B, gx3);
989
++    BN_mod(base, base, N, ctx);
990
++    if (BigIntCmpWord(base, 0) < 0) {
991
++	BN_add(base, base, N);
992
+     }
993
+ #endif
994
+     
995
+     /* S = base^aux % N */
996
+-    BN_init(&S);
997
+-    BN_mod_exp(&S, &base, &aux, N, ctx);
998
++    BN_mod_exp(S, base, aux, N, ctx);
999
+     
1000
+     /* K = H(S) */
1001
+-    r = MakeHash(text->md, K, Klen, "%m", &S);
1002
++    r = MakeHash(text->md, K, Klen, "%m", S);
1003
+     if (r) goto err;
1004
+     
1005
+     r = SASL_OK;
1006
+     
1007
+   err:
1008
+     BN_CTX_free(ctx);
1009
+-    BN_clear_free(&x);
1010
+-    BN_clear_free(&u);
1011
+-    BN_clear_free(&aux);
1012
+-    BN_clear_free(&gx);
1013
+-    BN_clear_free(&gx3);
1014
+-    BN_clear_free(&base);
1015
+-    BN_clear_free(&S);
1016
++    BN_clear_free(x);
1017
++    BN_clear_free(u);
1018
++    BN_clear_free(aux);
1019
++    BN_clear_free(gx);
1020
++    BN_clear_free(gx3);
1021
++    BN_clear_free(base);
1022
++    BN_clear_free(S);
1023
+     
1024
+     return r;
1025
+ }
1026
+@@ -2709,7 +2764,7 @@ static int srp_client_mech_new(void *glo
1027
+     }
1028
+     
1029
+     memset(text, 0, sizeof(context_t));
1030
+-    
1031
++
1032
+     text->state = 1;
1033
+     text->utils = params->utils;
1034
+ 
1035
+@@ -2866,7 +2921,7 @@ srp_client_mech_step2(context_t *text,
1036
+     }
1037
+ 
1038
+     /* Check N and g to see if they are one of the recommended pairs */
1039
+-    result = check_N_and_g(params->utils, &text->N, &text->g);
1040
++    result = check_N_and_g(params->utils, text->N, text->g);
1041
+     if (result) {
1042
+ 	params->utils->log(NULL, SASL_LOG_ERR,
1043
+ 			   "Values of 'N' and 'g' are not recommended\n");
1044
+@@ -2874,7 +2929,7 @@ srp_client_mech_step2(context_t *text,
1045
+     }
1046
+     
1047
+     /* Per [SRP]: reject B <= 0, B >= N */
1048
+-    if (BigIntCmpWord(&text->B, 0) <= 0 || BN_cmp(&text->B, &text->N) >= 0) {
1049
++    if (BigIntCmpWord(text->B, 0) <= 0 || BN_cmp(text->B, text->N) >= 0) {
1050
+ 	SETERROR(params->utils, "Illegal value for 'B'\n");
1051
+ 	result = SASL_BADPROT;
1052
+ 	goto cleanup;
1053
+@@ -2913,7 +2968,7 @@ srp_client_mech_step2(context_t *text,
1054
+     }
1055
+ 
1056
+     /* Calculate A */
1057
+-    result = CalculateA(text, &text->N, &text->g, &text->a, &text->A);
1058
++    result = CalculateA(text, text->N, text->g, &text->a, &text->A);
1059
+     if (result) {
1060
+ 	params->utils->seterror(params->utils->conn, 0, 
1061
+ 				"Error calculating A");
1062
+@@ -2924,7 +2979,7 @@ srp_client_mech_step2(context_t *text,
1063
+     result = ClientCalculateK(text, text->salt, text->saltlen,
1064
+ 			      (char *) oparams->authid, 
1065
+ 			      text->password->data, text->password->len,
1066
+-			      &text->N, &text->g, &text->a, &text->A, &text->B,
1067
++			      text->N, text->g, text->a, text->A, text->B,
1068
+ 			      text->K, &text->Klen);
1069
+     if (result) {
1070
+ 	params->utils->log(NULL, SASL_LOG_ERR,
1071
+@@ -2933,8 +2988,8 @@ srp_client_mech_step2(context_t *text,
1072
+     }
1073
+     
1074
+     /* Calculate M1 (client evidence) */
1075
+-    result = CalculateM1(text, &text->N, &text->g, (char *) oparams->authid,
1076
+-			 text->salt, text->saltlen, &text->A, &text->B,
1077
++    result = CalculateM1(text, text->N, text->g, (char *) oparams->authid,
1078
++			 text->salt, text->saltlen, text->A, text->B,
1079
+ 			 text->K, text->Klen, (char *) oparams->user,
1080
+ 			 text->server_options, text->M1, &text->M1len);
1081
+     if (result) {
1082
+@@ -2944,7 +2999,7 @@ srp_client_mech_step2(context_t *text,
1083
+     }
1084
+ 
1085
+     /* Create cIV (client initial vector) */
1086
+-    text->utils->rand(text->utils->rpool, text->cIV, sizeof(text->cIV));
1087
++    text->utils->rand(text->utils->rpool, (char *) text->cIV, sizeof(text->cIV));
1088
+     
1089
+     /* Send out:
1090
+      *
1091
+@@ -2957,7 +3012,7 @@ srp_client_mech_step2(context_t *text,
1092
+      */
1093
+     result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
1094
+ 			clientoutlen, "%m%o%s%o",
1095
+-			&text->A, text->M1len, text->M1, text->client_options,
1096
++			text->A, text->M1len, text->M1, text->client_options,
1097
+ 			sizeof(text->cIV), text->cIV);
1098
+     if (result) {
1099
+ 	params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
1100
+@@ -2985,13 +3040,13 @@ srp_client_mech_step3(context_t *text,
1101
+ 		      sasl_out_params_t *oparams)
1102
+ {
1103
+     int result;    
1104
+-    char *M2 = NULL, *sIV = NULL; /* don't free */
1105
++    unsigned char *M2 = NULL, *sIV = NULL; /* don't free */
1106
+     char *sid = NULL;
1107
+-    int M2len, sIVlen;
1108
++    unsigned int M2len, sIVlen;
1109
+     uint32 ttl;
1110
+-    int i;
1111
+-    char myM2[EVP_MAX_MD_SIZE];
1112
+-    int myM2len;
1113
++    unsigned int i;
1114
++    unsigned char myM2[EVP_MAX_MD_SIZE];
1115
++    unsigned int myM2len;
1116
+     
1117
+     /* Expect:
1118
+      *
1119
+@@ -3012,7 +3067,7 @@ srp_client_mech_step3(context_t *text,
1120
+     }
1121
+ 
1122
+     /* calculate our own M2 */
1123
+-    result = CalculateM2(text, &text->A, text->M1, text->M1len,
1124
++    result = CalculateM2(text, text->A, text->M1, text->M1len,
1125
+ 			 text->K, text->Klen, (char *) oparams->user,
1126
+ 			 text->client_options, "", 0,
1127
+ 			 myM2, &myM2len);
1128
+@@ -3182,3 +3237,4 @@ int srp_client_plug_init(const sasl_util
1129
+     
1130
+     return SASL_OK;
1131
+ }
1132
++
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:	Cyrus Simple Authentication Service Layer (SASL) library
2 2
 Name:		cyrus-sasl
3 3
 Version:	2.1.26
4
-Release:	9%{?dist}
4
+Release:	10%{?dist}
5 5
 License:	Custom
6 6
 URL:		http://cyrusimap.web.cmu.edu/
7 7
 Group:		System Environment/Security
... ...
@@ -128,6 +128,8 @@ rm -rf %{buildroot}/*
128 128
 %{_datadir}/licenses/%{name}/LICENSE
129 129
 %{_mandir}/man8/saslauthd.8.gz
130 130
 %changelog
131
+*   Tue Nov 21 2017 Anish Swaminathan <anishs@vmware.com>  2.1.26-10
132
+-   Update patch for memory leak fix
131 133
 *   Tue Oct 10 2017 Anish Swaminathan <anishs@vmware.com>  2.1.26-9
132 134
 -   Add patch for memory leak fix
133 135
 *   Thu May 26 2016 Divya Thaluru <dthaluru@vmware.com>  2.1.26-8