Imported Upstream version 0.63.0
[hcoop/debian/courier-authlib.git] / authsaslclientcram.c
CommitLineData
ac40fd9e 1/* $Id: authsaslclientcram.c,v 1.5 2008/07/10 02:43:55 mrsam Exp $ */
d9898ee8 2
3/*
ac40fd9e 4** Copyright 2000-2008 Double Precision, Inc. See COPYING for
d9898ee8 5** distribution information.
6*/
7
8#include "courier_auth_config.h"
9#include "courierauthsasl.h"
d9898ee8 10#include "libhmac/hmac.h"
d9898ee8 11#include "authsaslclient.h"
12#include <stdlib.h>
13#include <stdio.h>
14#include <ctype.h>
15#include <string.h>
16#include <errno.h>
17
d9898ee8 18int authsaslclient_cram(const struct authsaslclientinfo *info,
ac40fd9e 19 const char *challenge,
20 const struct hmac_hashinfo *hashinfo)
d9898ee8 21{
22char *base64buf=malloc(strlen(challenge)+1);
23unsigned char *keybuf;
24char *p;
25const char *userid=info->userid ? info->userid:"";
26const char *password=info->password ? info->password:"";
27int i;
28
29 if (!base64buf)
30 {
31 perror("malloc");
32 return (AUTHSASL_ERROR);
33 }
34 strcpy(base64buf, challenge);
35
36 if ( (i=authsasl_frombase64(base64buf))<0 ||
37 (keybuf=(unsigned char *)malloc(hashinfo->hh_L*3)) == 0)
38 {
39 free(base64buf);
40 perror("malloc");
41 return (AUTHSASL_ERROR);
42 }
43
44 hmac_hashkey( hashinfo, password, strlen(password),
45 keybuf, keybuf+hashinfo->hh_L );
46
47 hmac_hashtext( hashinfo, base64buf, i,
48 keybuf, keybuf+hashinfo->hh_L,
49 keybuf+hashinfo->hh_L*2);
50
51 free(base64buf);
52 base64buf=malloc(strlen(userid)+2+hashinfo->hh_L*2);
53 if (!base64buf)
54 {
55 perror("malloc");
56 free(keybuf);
57 return (AUTHSASL_ERROR);
58 }
59 strcat(strcpy(base64buf, userid), " ");
60 p=base64buf+strlen(base64buf);
61 for (i=0; i<hashinfo->hh_L; i++)
62 {
63 static const char xdigit[]="0123456789abcdef";
64 int c=keybuf[hashinfo->hh_L*2+i];
65
66 *p++ = xdigit[ (c >> 4) & 0x0F ];
67 *p++ = xdigit[c & 0x0F];
68 }
69 *p=0;
70 free(keybuf);
71 keybuf=(unsigned char *)authsasl_tobase64(base64buf, -1);
72 free(base64buf);
73
74 if (!keybuf)
75 {
76 perror("malloc");
77 free(keybuf);
78 return (AUTHSASL_ERROR);
79 }
80 i= (*info->final_conv_func)((char *)keybuf, info->conv_func_arg);
81 free(keybuf);
82 return (i);
83}