8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libldap5 / sources / ldap / common / cram_md5.c
blob7b662829c72ee1cb9720334bfe55491bcb81453a
1 /*
2 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 #pragma ident "%Z%%M% %I% %E% SMI"
8 #include <stdio.h>
9 #include <string.h>
10 #include "lber.h"
11 #include "ldap.h"
12 #include "ldap-int.h"
13 #include <sys/types.h>
14 #include <strings.h>
15 #include "sec.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)
22 MD5_CTX context;
23 unsigned char k_ipad[65];
24 unsigned char k_opad[65];
25 unsigned char tk[16];
26 int i;
28 if (key_len > 64){
29 MD5_CTX tctx;
31 (void) MD5Init(&tctx);
32 (void) MD5Update(&tctx, key, key_len);
33 (void) MD5Final(tk, &tctx);
34 key = tk;
35 key_len = 16;
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);
43 for (i=0; i<64; i++){
44 k_ipad[i] ^= 0x36;
45 k_opad[i] ^= 0x5c;
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);
61 return;
64 int ldap_sasl_cram_md5_bind_s(
65 LDAP *ld,
66 char *dn,
67 struct berval *cred,
68 LDAPControl **serverctrls,
69 LDAPControl **clientctrls )
71 int res;
72 struct berval *challenge = NULL;
73 struct berval resp;
74 unsigned char digest[16];
75 char *theHDigest;
77 if (dn == NULL){
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){
85 return (res);
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);
96 challenge = NULL;
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);
109 free(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);
114 free(resp.bv_val);
115 return (res);