2 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
13 #include <sys/types.h>
17 /* text is the challenge, key is the password, digest is an allocated
18 buffer (min 16 chars) which will contain the resulting digest */
19 void hmac_md5(unsigned char *text
, int text_len
, unsigned char *key
,
20 int key_len
, unsigned char *digest
)
23 unsigned char k_ipad
[65];
24 unsigned char k_opad
[65];
31 (void) MD5Init(&tctx
);
32 (void) MD5Update(&tctx
, key
, key_len
);
33 (void) MD5Final(tk
, &tctx
);
38 bzero(k_ipad
, sizeof (k_ipad
));
39 bzero(k_opad
, sizeof (k_opad
));
40 bcopy(key
, k_ipad
, key_len
);
41 bcopy(key
, k_opad
, key_len
);
48 /* Perform inner MD5 */
49 (void) MD5Init(&context
);
50 (void) MD5Update(&context
, k_ipad
, 64);
51 (void) MD5Update(&context
, text
, text_len
);
52 (void) MD5Final(digest
, &context
);
54 /* Perform outer MD5 */
55 (void) MD5Init(&context
);
56 (void) MD5Update(&context
, k_opad
, 64);
57 (void) MD5Update(&context
, digest
, 16);
59 (void) MD5Final(digest
, &context
);
64 int ldap_sasl_cram_md5_bind_s(
68 LDAPControl
**serverctrls
,
69 LDAPControl
**clientctrls
)
72 struct berval
*challenge
= NULL
;
74 unsigned char digest
[16];
78 return (LDAP_PARAM_ERROR
);
81 bzero(digest
, sizeof (digest
));
83 if ((res
= ldap_sasl_bind_s(ld
, NULL
, LDAP_SASL_CRAM_MD5
, NULL
, serverctrls
, clientctrls
, &challenge
))
84 != LDAP_SASL_BIND_IN_PROGRESS
){
87 if (challenge
== NULL
){
88 return (LDAP_PARAM_ERROR
);
91 LDAPDebug (LDAP_DEBUG_TRACE
, "SASL challenge: %s\n", challenge
->bv_val
, 0, 0);
93 hmac_md5((unsigned char *)challenge
->bv_val
, challenge
->bv_len
,
94 (unsigned char *)cred
->bv_val
, cred
->bv_len
, digest
);
95 ber_bvfree(challenge
);
98 theHDigest
= hexa_print(digest
, 16);
99 if (theHDigest
== NULL
){
100 return (LDAP_NO_MEMORY
);
103 resp
.bv_len
= (strlen(dn
) + 32 + 1);
104 if ((resp
.bv_val
= (char *)malloc(resp
.bv_len
+1)) == NULL
) {
105 return(LDAP_NO_MEMORY
);
108 sprintf(resp
.bv_val
, "%s %s", dn
, theHDigest
);
111 LDAPDebug (LDAP_DEBUG_TRACE
, "SASL response: %s\n", resp
.bv_val
, 0, 0);
112 res
= ldap_sasl_bind_s(ld
, NULL
, LDAP_SASL_CRAM_MD5
, &resp
, serverctrls
, clientctrls
, &challenge
);