]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservcrypto.c
4 #include "../core/error.h"
5 #include "../lib/prng.h"
6 #include "../lib/sha1.h"
7 #include "../lib/sha2.h"
8 #include "../lib/md5.h"
9 #include "../lib/hmac.h"
13 void chanservcryptoinit(void) {
16 FILE *e
= fopen(ENTROPYSOURCE
, "rb");
18 Error("chanserv",ERR_STOP
,"Unable to open entropy source.");
19 /* shouldn't be running now... */
22 ret
= fread(rng
.randrsl
, 1, sizeof(rng
.randrsl
), e
);
25 if(ret
!= sizeof(rng
.randrsl
)) {
26 Error("chanserv",ERR_STOP
,"Unable to read entropy.");
27 /* shouldn't be running now... */
33 ub4
cs_getrandint(void) {
37 void cs_getrandbytes(unsigned char *buf
, size_t bytes
) {
38 for(;bytes
>0;bytes
-=4,buf
+=4) {
39 ub4 b
= cs_getrandint();
44 const char *cs_cralgorithmlist(void) {
45 return "HMAC-MD5 HMAC-SHA-1 HMAC-SHA-256";
48 int crsha1(char *username
, const char *password
, const char *challenge
, const char *response
) {
52 unsigned char digest
[20];
53 char hexbuf
[sizeof(digest
) * 2 + 1];
56 /* not sure how this helps but the RFC says to do it... */
58 SHA1Update(&ctx
, (unsigned char *)password
, strlen(password
));
59 SHA1Final(digest
, &ctx
);
61 snprintf(buf
, sizeof(buf
), "%s:%s", username
, hmac_printhex(digest
, hexbuf
, sizeof(digest
)));
64 SHA1Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
65 SHA1Final(digest
, &ctx
);
67 hmacsha1_init(&hmac
, (unsigned char *)hmac_printhex(digest
, hexbuf
, sizeof(digest
)), sizeof(digest
) * 2);
68 hmacsha1_update(&hmac
, (unsigned char *)challenge
, strlen(challenge
));
69 hmacsha1_final(&hmac
, digest
);
71 hmac_printhex(digest
, hexbuf
, sizeof(digest
));
73 if(!strcasecmp(hmac_printhex(digest
, hexbuf
, sizeof(digest
)), response
))
79 int crsha256(char *username
, const char *password
, const char *challenge
, const char *response
) {
83 unsigned char digest
[32];
84 char hexbuf
[sizeof(digest
) * 2 + 1];
87 /* not sure how this helps but the RFC says to do it... */
89 SHA256_Update(&ctx
, (unsigned char *)password
, strlen(password
));
90 SHA256_Final(digest
, &ctx
);
92 snprintf(buf
, sizeof(buf
), "%s:%s", username
, hmac_printhex(digest
, hexbuf
, sizeof(digest
)));
95 SHA256_Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
96 SHA256_Final(digest
, &ctx
);
98 hmacsha256_init(&hmac
, (unsigned char *)hmac_printhex(digest
, hexbuf
, sizeof(digest
)), sizeof(digest
) * 2);
99 hmacsha256_update(&hmac
, (unsigned char *)challenge
, strlen(challenge
));
100 hmacsha256_final(&hmac
, digest
);
102 if(!strcasecmp(hmac_printhex(digest
, hexbuf
, sizeof(digest
)), response
))
108 int crmd5(char *username
, const char *password
, const char *challenge
, const char *response
) {
112 unsigned char digest
[16];
113 char hexbuf
[sizeof(digest
) * 2 + 1];
116 /* not sure how this helps but the RFC says to do it... */
118 MD5Update(&ctx
, (unsigned char *)password
, strlen(password
));
119 MD5Final(digest
, &ctx
);
121 snprintf(buf
, sizeof(buf
), "%s:%s", username
, hmac_printhex(digest
, hexbuf
, sizeof(digest
)));
124 MD5Update(&ctx
, (unsigned char *)buf
, strlen(buf
));
125 MD5Final(digest
, &ctx
);
127 hmacmd5_init(&hmac
, (unsigned char *)hmac_printhex(digest
, hexbuf
, sizeof(digest
)), sizeof(digest
) * 2);
128 hmacmd5_update(&hmac
, (unsigned char *)challenge
, strlen(challenge
));
129 hmacmd5_final(&hmac
, digest
);
131 if(!strcasecmp(hmac_printhex(digest
, hexbuf
, sizeof(digest
)), response
))
137 CRAlgorithm
cs_cralgorithm(const char *algorithm
) {
138 if(!strcasecmp(algorithm
, "hmac-sha-1"))
141 if(!strcasecmp(algorithm
, "hmac-sha-256"))
144 if(!strcasecmp(algorithm
, "hmac-md5"))
150 char *cs_calcchallenge(const unsigned char *entropy
) {
151 unsigned char buf
[20];
152 static char hexbuf
[sizeof(buf
) * 2 + 1];
156 /* we can maybe add a salt here in the future */
157 SHA1Update(&ctx
, entropy
, ENTROPYLEN
);
158 SHA1Final(buf
, &ctx
);
160 hmac_printhex(buf
, hexbuf
, sizeof(buf
));