]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservcrypto.c
5 #include "../core/error.h"
6 #include "../lib/prng.h"
7 #include "../lib/sha1.h"
8 #include "../lib/sha2.h"
9 #include "../lib/md5.h"
10 #include "../lib/hmac.h"
14 void chanservcryptoinit(void) {
17 FILE *e
= fopen(ENTROPYSOURCE
, "rb");
19 Error("chanserv",ERR_STOP
,"Unable to open entropy source.");
20 /* shouldn't be running now... */
23 ret
= fread(rng
.randrsl
, 1, sizeof(rng
.randrsl
), e
);
26 if(ret
!= sizeof(rng
.randrsl
)) {
27 Error("chanserv",ERR_STOP
,"Unable to read entropy.");
28 /* shouldn't be running now... */
34 ub4
cs_getrandint(void) {
38 void cs_getrandbytes(unsigned char *buf
, size_t bytes
) {
39 for(;bytes
>0;bytes
-=4,buf
+=4) {
40 ub4 b
= cs_getrandint();
45 const char *cs_cralgorithmlist(void) {
46 return "HMAC-MD5 HMAC-SHA-1 HMAC-SHA-256";
49 int crsha1(char *username
, const char *password
, const char *challenge
, const char *response
) {
53 unsigned char digest
[20];
54 char hexbuf
[sizeof(digest
) * 2 + 1];
57 /* not sure how this helps but the RFC says to do it... */
59 SHA1Update(&ctx
, (unsigned char *)password
, strlen(password
));
60 SHA1Final(digest
, &ctx
);
62 snprintf(buf
, sizeof(buf
), "%s:%s", username
, hmac_printhex(digest
, hexbuf
, sizeof(digest
)));
65 SHA1Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
66 SHA1Final(digest
, &ctx
);
68 hmacsha1_init(&hmac
, (unsigned char *)hmac_printhex(digest
, hexbuf
, sizeof(digest
)), sizeof(digest
) * 2);
69 hmacsha1_update(&hmac
, (unsigned char *)challenge
, strlen(challenge
));
70 hmacsha1_final(&hmac
, digest
);
72 hmac_printhex(digest
, hexbuf
, sizeof(digest
));
74 if(!strcasecmp(hmac_printhex(digest
, hexbuf
, sizeof(digest
)), response
))
80 int crsha256(char *username
, const char *password
, const char *challenge
, const char *response
) {
84 unsigned char digest
[32];
85 char hexbuf
[sizeof(digest
) * 2 + 1];
88 /* not sure how this helps but the RFC says to do it... */
90 SHA256_Update(&ctx
, (unsigned char *)password
, strlen(password
));
91 SHA256_Final(digest
, &ctx
);
93 snprintf(buf
, sizeof(buf
), "%s:%s", username
, hmac_printhex(digest
, hexbuf
, sizeof(digest
)));
96 SHA256_Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
97 SHA256_Final(digest
, &ctx
);
99 hmacsha256_init(&hmac
, (unsigned char *)hmac_printhex(digest
, hexbuf
, sizeof(digest
)), sizeof(digest
) * 2);
100 hmacsha256_update(&hmac
, (unsigned char *)challenge
, strlen(challenge
));
101 hmacsha256_final(&hmac
, digest
);
103 if(!strcasecmp(hmac_printhex(digest
, hexbuf
, sizeof(digest
)), response
))
109 int crmd5(char *username
, const char *password
, const char *challenge
, const char *response
) {
113 unsigned char digest
[16];
114 char hexbuf
[sizeof(digest
) * 2 + 1];
117 /* not sure how this helps but the RFC says to do it... */
119 MD5Update(&ctx
, (unsigned char *)password
, strlen(password
));
120 MD5Final(digest
, &ctx
);
122 snprintf(buf
, sizeof(buf
), "%s:%s", username
, hmac_printhex(digest
, hexbuf
, sizeof(digest
)));
125 MD5Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
126 MD5Final(digest
, &ctx
);
128 hmacmd5_init(&hmac
, (unsigned char *)hmac_printhex(digest
, hexbuf
, sizeof(digest
)), sizeof(digest
) * 2);
129 hmacmd5_update(&hmac
, (unsigned char *)challenge
, strlen(challenge
));
130 hmacmd5_final(&hmac
, digest
);
132 if(!strcasecmp(hmac_printhex(digest
, hexbuf
, sizeof(digest
)), response
))
138 CRAlgorithm
cs_cralgorithm(const char *algorithm
) {
139 if(!strcasecmp(algorithm
, "hmac-sha-1"))
142 if(!strcasecmp(algorithm
, "hmac-sha-256"))
145 if(!strcasecmp(algorithm
, "hmac-md5"))
151 char *cs_calcchallenge(const unsigned char *entropy
) {
152 unsigned char buf
[20];
153 static char hexbuf
[sizeof(buf
) * 2 + 1];
157 /* we can maybe add a salt here in the future */
158 SHA1Update(&ctx
, entropy
, ENTROPYLEN
);
159 SHA1Final(buf
, &ctx
);
161 hmac_printhex(buf
, hexbuf
, sizeof(buf
));
166 int cs_checkhashpass(const char *username
, const char *password
, const char *junk
, const char *hash
) {
168 unsigned char digest
[16];
169 char hexbuf
[sizeof(digest
) * 2 + 1], buf
[512];
171 snprintf(buf
, sizeof(buf
), "%s %s%s%s", username
, password
, junk
?" ":"", junk
?junk
:"");
174 MD5Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
175 MD5Final(digest
, &ctx
);
177 if(strcasecmp(hash
, hmac_printhex(digest
, hexbuf
, sizeof(digest
))))