File Coverage

inc/CryptX_Digest.xs.inc
Criterion Covered Total %
statement 80 83 96.3
branch 55 88 62.5
condition n/a
subroutine n/a
pod n/a
total 135 171 78.9


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::Digest
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::Digest
6             new(char * cname, char * pname = NULL)
7             CODE:
8             {
9             int rv;
10             int id;
11 3388 50         char *digest_name = strcmp(cname, "Crypt::Digest") == 0 ? pname : cname;
12              
13 3388           id = cryptx_internal_find_hash(digest_name);
14 3388 50         if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name);
15              
16 3388           Newz(0, RETVAL, 1, struct digest_struct);
17 3388 50         if (!RETVAL) croak("FATAL: Newz failed");
18              
19 3388           RETVAL->desc = &hash_descriptor[id];
20 3388           rv = RETVAL->desc->init(&RETVAL->state);
21 3388 50         if (rv != CRYPT_OK) {
22 0           Safefree(RETVAL);
23 0           croak("FATAL: digest setup failed: %s", error_to_string(rv));
24             }
25             }
26             OUTPUT:
27             RETVAL
28              
29             void
30             DESTROY(Crypt::Digest self)
31             CODE:
32             {
33 3478           zeromem(self, sizeof(*self));
34 3478           Safefree(self);
35             }
36              
37             void
38             reset(Crypt::Digest self)
39             PPCODE:
40             {
41             int rv;
42 33           rv = self->desc->init(&self->state);
43 33 50         if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv));
44 33           self->finalized = 0;
45 33 50         XPUSHs(ST(0)); /* return self */
46             }
47              
48             Crypt::Digest
49             clone(Crypt::Digest self)
50             CODE:
51 90 50         if (self->desc != NULL && cryptx_internal_noclone_hash(self->desc->name)) {
    50          
52 0           croak("FATAL: clone is not supported for given hash state");
53             }
54 90           Newz(0, RETVAL, 1, struct digest_struct);
55 90 50         if (!RETVAL) croak("FATAL: Newz failed");
56 90           Copy(self, RETVAL, 1, struct digest_struct);
57             OUTPUT:
58             RETVAL
59              
60             void
61             add(Crypt::Digest self, ...)
62             PPCODE:
63             {
64             STRLEN inlen;
65             int rv, i;
66             unsigned char *in;
67              
68 3420 100         if (self->finalized) croak("FATAL: digest object already finalized");
69 6873 100         for(i = 1; i < items; i++) {
70 3486           in = (unsigned char *)SvPVbyte(ST(i), inlen);
71 3486 100         if (inlen > 0) {
72 3440           rv = self->desc->process(&self->state, in, (unsigned long)inlen);
73 3440 50         if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv));
74             }
75             }
76 3387 50         XPUSHs(ST(0)); /* return self */
77             }
78              
79             SV *
80             digest(Crypt::Digest self)
81             ALIAS:
82             hexdigest = 1
83             b64digest = 2
84             b64udigest = 3
85             CODE:
86             {
87             int rv;
88             unsigned long outlen;
89             unsigned char hash[MAXBLOCKSIZE];
90             char out[MAXBLOCKSIZE*2+1];
91              
92 3447 100         if (self->finalized) croak("FATAL: digest object already finalized");
93 3381           rv = self->desc->done(&self->state, hash);
94 3381 50         if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
95 3381           self->finalized = 1;
96              
97 3381           outlen = sizeof(out);
98 3381 100         if (ix == 3) {
99 165           rv = base64url_encode(hash, self->desc->hashsize, out, &outlen);
100 165 50         if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv));
101 165           RETVAL = newSVpvn(out, outlen);
102             }
103 3216 100         else if (ix == 2) {
104 297           rv = base64_encode(hash, self->desc->hashsize, out, &outlen);
105 297 50         if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv));
106 297           RETVAL = newSVpvn(out, outlen);
107             }
108 2919 100         else if (ix == 1) {
109 2622           rv = base16_encode(hash, self->desc->hashsize, out, &outlen, 0);
110 2622 50         if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
111 2622           RETVAL = newSVpvn(out, outlen);
112             }
113             else {
114 297           RETVAL = newSVpvn((char *) hash, self->desc->hashsize);
115             }
116             }
117             OUTPUT:
118             RETVAL
119              
120             SV *
121             digest_data(char * digest_name, ...)
122             ALIAS:
123             digest_data_hex = 1
124             digest_data_b64 = 2
125             digest_data_b64u = 3
126             CODE:
127             {
128             STRLEN inlen;
129             int rv, id, i;
130             unsigned char *in, hash[MAXBLOCKSIZE];
131 991           unsigned long len = sizeof(hash), outlen;
132             char out[MAXBLOCKSIZE*2+1];
133             hash_state md;
134              
135 991           id = cryptx_internal_find_hash(digest_name);
136 991 50         if (id == -1) croak("FATAL: find_digest failed for '%s'", digest_name);
137              
138             /* digest_data("SHA1", $data1, $data2, $data3); */
139 991           len = hash_descriptor[id].hashsize;
140 991           rv = hash_descriptor[id].init(&md);
141 991 50         if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv));
142 2510 100         for (i = 1; i < items; i++) {
143 1519           in = (unsigned char *)SvPVbyte(ST(i), inlen);
144 1519 100         if (inlen > 0) {
145 1288           rv = hash_descriptor[id].process(&md, in, (unsigned long)inlen);
146 1288 50         if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv));
147             }
148             }
149 991           rv = hash_descriptor[id].done(&md, hash);
150 991 50         if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
151              
152 991           outlen = sizeof(out);
153 991 100         if (ix == 3) {
154 165           rv = base64url_encode(hash, len, out, &outlen);
155 165 50         if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv));
156 165           RETVAL = newSVpvn(out, outlen);
157             }
158 826 100         else if (ix == 2) {
159 264           rv = base64_encode(hash, len, out, &outlen);
160 264 50         if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv));
161 264           RETVAL = newSVpvn(out, outlen);
162             }
163 562 100         else if (ix == 1) {
164 266           rv = base16_encode(hash, len, out, &outlen, 0);
165 266 50         if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
166 266           RETVAL = newSVpvn(out, outlen);
167             }
168             else {
169 296           RETVAL = newSVpvn((char *) hash, len);
170             }
171             }
172             OUTPUT:
173             RETVAL
174              
175             int
176             hashsize(SV * param, char * extra = NULL)
177             CODE:
178             {
179 1950 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Digest")) {
    50          
180 33           IV tmp = SvIV((SV*)SvRV(param));
181 33           Crypt__Digest obj = INT2PTR(Crypt__Digest, tmp);
182 33           RETVAL = obj->desc->hashsize;
183             }
184             else {
185             char *digest_name;
186             STRLEN plen;
187             int rv, id;
188 1917 50         digest_name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Digest") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
189 1917           id = cryptx_internal_find_hash(digest_name);
190 1917 50         if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name);
191 1917           rv = hash_descriptor[id].hashsize;
192 1917 50         if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);;
193 1917           RETVAL = rv;
194             }
195             }
196             OUTPUT:
197             RETVAL