2 * Filename : decrypt.xs
4 * Author : Paul Marquess
5 * Date : 20th July 2000
13 #include "../Call/ppport.h"
16 static int fdebug = 0;
19 /* constants specific to the encryption format */
20 #define CRYPT_MAGIC_1 0xff
21 #define CRYPT_MAGIC_2 0x00
27 #define SET_LEN(sv,len) \
28 do { SvPVX(sv)[len] = '\0'; SvCUR_set(sv, len); } while (0)
31 static unsigned XOR [BLOCKSIZE] = {'P', 'e', 'r', 'l' } ;
34 /* Internal defines */
35 #ifdef PERL_FILTER_EXISTS
36 # define CORE_FILTER_COUNT \
37 (PL_parser && PL_parser->rsfp_filters ? av_len(PL_parser->rsfp_filters) : 0)
39 # define CORE_FILTER_COUNT \
40 (PL_rsfp_filters ? av_len(PL_rsfp_filters) : 0)
43 #define FILTER_COUNT(s) IoPAGE(s)
44 #define FILTER_LINE_NO(s) IoLINES(s)
45 #define FIRST_TIME(s) IoLINES_LEFT(s)
47 #define ENCRYPT_GV(s) IoTOP_GV(s)
48 #define ENCRYPT_SV(s) ((SV*) ENCRYPT_GV(s))
49 #define ENCRYPT_BUFFER(s) SvPVX(ENCRYPT_SV(s))
50 #define CLEAR_ENCRYPT_SV(s) SvCUR_set(ENCRYPT_SV(s), 0)
52 #define DECRYPT_SV(s) s
53 #define DECRYPT_BUFFER(s) SvPVX(DECRYPT_SV(s))
54 #define CLEAR_DECRYPT_SV(s) SvCUR_set(DECRYPT_SV(s), 0)
55 #define DECRYPT_BUFFER_LEN(s) SvCUR(DECRYPT_SV(s))
56 #define DECRYPT_OFFSET(s) IoPAGE_LEN(s)
57 #define SET_DECRYPT_BUFFER_LEN(s,n) SvCUR_set(DECRYPT_SV(s), n)
60 Decrypt(SV *in_sv, SV *out_sv)
62 /* Here is where the actual decryption takes place */
64 unsigned char * in_buffer = (unsigned char *) SvPVX(in_sv) ;
65 unsigned char * out_buffer ;
66 unsigned size = SvCUR(in_sv) ;
67 unsigned index = size ;
70 /* make certain that the output buffer is big enough */
71 /* as the output from the decryption can never be larger than */
72 /* the input buffer, make it that size */
73 SvGROW(out_sv, size) ;
74 out_buffer = (unsigned char *) SvPVX(out_sv) ;
77 for (i = 0 ; i < size ; ++i)
78 out_buffer[i] = (unsigned char)( XOR[i] ^ in_buffer[i] ) ;
80 /* input has been consumed, so set length to 0 */
83 /* set decrypt buffer length */
84 SET_LEN(out_sv, index) ;
86 /* return the size of the decrypt buffer */
91 ReadBlock(int idx, SV *sv, unsigned size)
92 { /* read *exactly* size bytes from the next filter */
95 int n = FILTER_READ(idx, sv, i) ;
96 if (n <= 0 && i==size) /* eof/error when nothing read so far */
98 if (n <= 0) /* eof/error when something already read */
109 /* If the encrypted data starts with a header or needs to do some
110 initialisation it can be done here
112 In this case the encrypted data has to start with a fingerprint,
116 SV * sv = FILTER_DATA(idx) ;
117 unsigned char * buffer ;
120 /* read the header */
121 if (ReadBlock(idx+1, sv, HEADERSIZE) != HEADERSIZE)
122 croak("truncated file") ;
124 buffer = (unsigned char *) SvPVX(sv) ;
126 /* check for fingerprint of encrypted data */
127 if (buffer[0] != CRYPT_MAGIC_1 || buffer[1] != CRYPT_MAGIC_2)
128 croak( "bad encryption format" );
137 filter_decrypt(pTHX_ int idx, SV *buf_sv, int maxlen)
139 SV *my_sv = FILTER_DATA(idx);
145 /* check if this is the first time through */
146 if (FIRST_TIME(my_sv)) {
148 /* Mild paranoia mode - make sure that no extra filters have */
149 /* been applied on the same line as the use Filter::decrypt */
150 if (CORE_FILTER_COUNT > FILTER_COUNT(my_sv) )
151 croak("too many filters") ;
153 /* As this is the first time through, so deal with any */
154 /* initialisation required */
157 FIRST_TIME(my_sv) = FALSE ;
158 SET_LEN(DECRYPT_SV(my_sv), 0) ;
159 SET_LEN(ENCRYPT_SV(my_sv), 0) ;
160 DECRYPT_OFFSET(my_sv) = 0 ;
165 warn("**** In filter_decrypt - maxlen = %d, len buf = %d idx = %d\n",
166 maxlen, SvCUR(buf_sv), idx ) ;
171 /* anything left from last time */
172 if ((n = SvCUR(DECRYPT_SV(my_sv)))) {
174 out_ptr = SvPVX(DECRYPT_SV(my_sv)) + DECRYPT_OFFSET(my_sv) ;
180 warn("BLOCK(%d): size = %d, maxlen = %d\n",
184 sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
186 DECRYPT_OFFSET(my_sv) = 0 ;
187 SET_LEN(DECRYPT_SV(my_sv), 0) ;
190 DECRYPT_OFFSET(my_sv) += maxlen ;
191 SvCUR_set(DECRYPT_SV(my_sv), n - maxlen) ;
193 return SvCUR(buf_sv);
197 if ((p = ninstr(out_ptr, out_ptr + n, nl, nl + 1))) {
199 sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);
201 n = n - (p - out_ptr + 1);
202 DECRYPT_OFFSET(my_sv) += (p - out_ptr + 1) ;
203 SvCUR_set(DECRYPT_SV(my_sv), n) ;
206 warn("recycle %d - leaving %d, returning %d [%.999s]",
207 idx, n, SvCUR(buf_sv), SvPVX(buf_sv)) ;
210 return SvCUR(buf_sv);
212 else /* no EOL, so append the complete buffer */
213 sv_catpvn(buf_sv, out_ptr, n) ;
219 SET_LEN(DECRYPT_SV(my_sv), 0) ;
220 DECRYPT_OFFSET(my_sv) = 0 ;
222 /* read from the file into the encrypt buffer */
223 if ( (n = ReadBlock(idx+1, ENCRYPT_SV(my_sv), BLOCKSIZE)) <= 0)
225 /* Either EOF or an error */
229 warn ("filter_read %d returned %d , returning %d\n", idx, n,
230 (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n);
233 /* If the decrypt code needs to tidy up on EOF/error,
234 now is the time - here is a hook */
237 filter_del(filter_decrypt);
240 /* If error, return the code */
244 /* return what we have so far else signal eof */
245 return (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n;
250 warn(" filter_decrypt(%d): sub-filter returned %d: '%.999s'",
251 idx, n, SvPV(my_sv,PL_na));
254 /* Now decrypt a block */
255 n = Decrypt(ENCRYPT_SV(my_sv), DECRYPT_SV(my_sv)) ;
259 warn("Decrypt (%d) returned %d [%.999s]\n", idx, n, SvPVX(DECRYPT_SV(my_sv)) ) ;
266 MODULE = Filter::decrypt PACKAGE = Filter::decrypt
271 /* Check for the presence of the Perl Compiler */
272 if (gv_stashpvn("B", 1, FALSE))
273 croak("Aborting, Compiler detected") ;
275 /* Don't run if this module is dynamically linked */
276 if (!isALPHA(SvPV(GvSV(CvFILEGV(cv)), PL_na)[0]))
277 croak("module is dynamically linked. Recompile as a static module") ;
279 /* Don't run if compiled with DEBUGGING */
280 croak("recompile without -DDEBUGGING") ;
283 /* Double check that DEBUGGING hasn't been enabled */
285 croak("debugging flags detected") ;
295 SV * sv = newSV(BLOCKSIZE) ;
297 /* make sure the Perl debugger isn't enabled */
299 croak("debugger disabled") ;
301 filter_add(filter_decrypt, sv) ;
302 FIRST_TIME(sv) = TRUE ;
304 ENCRYPT_GV(sv) = (GV*) newSV(BLOCKSIZE) ;
305 (void)SvPOK_only(DECRYPT_SV(sv));
306 (void)SvPOK_only(ENCRYPT_SV(sv));
307 SET_LEN(DECRYPT_SV(sv), 0) ;
308 SET_LEN(ENCRYPT_SV(sv), 0) ;
311 /* remember how many filters are enabled */
312 FILTER_COUNT(sv) = CORE_FILTER_COUNT ;
313 /* and the line number */
314 FILTER_LINE_NO(sv) = PL_curcop->cop_line ;
321 /* filter_del(filter_decrypt); */