Overhauled the Perl interface (perl/*):
[openssl.git] / perl / openssl_cipher.xs
1
2 #include "openssl.h"
3
4 int boot_cipher()
5         {
6         SSLeay_add_all_ciphers();
7         return(1);
8         }
9
10 MODULE =  OpenSSL::Cipher       PACKAGE = OpenSSL::Cipher PREFIX = p5_EVP_C_
11
12 VERSIONCHECK: DISABLE
13
14 void
15 p5_EVP_C_new(...)
16         PREINIT:
17                 EVP_CIPHER_CTX *ctx;
18                 EVP_CIPHER *c;
19                 char *name;
20         PPCODE:
21                 if ((items == 1) && SvPOK(ST(0)))
22                         name=SvPV(ST(0),na);
23                 else if ((items == 2) && SvPOK(ST(1)))
24                         name=SvPV(ST(1),na);
25                 else
26                         croak("Usage: OpenSSL::Cipher::new(type)");
27                 PUSHs(sv_newmortal());
28                 c=EVP_get_cipherbyname(name);
29                 if (c != NULL)
30                         {
31                         ctx=malloc(sizeof(EVP_CIPHER_CTX));
32                         EVP_EncryptInit(ctx,c,NULL,NULL);
33                         sv_setref_pv(ST(0), "OpenSSL::Cipher", (void*)ctx);
34                         }
35
36 datum
37 p5_EVP_C_name(ctx)
38         EVP_CIPHER_CTX *ctx
39         CODE:
40                 RETVAL.dptr=OBJ_nid2ln(EVP_CIPHER_CTX_nid(ctx));
41                 RETVAL.dsize=strlen(RETVAL.dptr);
42         OUTPUT:
43                 RETVAL
44
45 int
46 p5_EVP_C_key_length(ctx)
47         EVP_CIPHER_CTX *ctx
48         CODE:
49                 RETVAL=EVP_CIPHER_CTX_key_length(ctx);
50         OUTPUT:
51                 RETVAL
52
53 int
54 p5_EVP_C_iv_length(ctx)
55         EVP_CIPHER_CTX *ctx
56         CODE:
57                 RETVAL=EVP_CIPHER_CTX_iv_length(ctx);
58         OUTPUT:
59                 RETVAL
60         
61 int
62 p5_EVP_C_block_size(ctx)
63         EVP_CIPHER_CTX *ctx
64         CODE:
65                 RETVAL=EVP_CIPHER_CTX_block_size(ctx);
66         OUTPUT:
67                 RETVAL
68         
69 void
70 p5_EVP_C_init(ctx,key,iv,enc)
71         EVP_CIPHER_CTX *ctx
72         datum key
73         datum iv
74         int enc
75         PREINIT:
76                 char loc_iv[EVP_MAX_IV_LENGTH];
77                 char loc_key[EVP_MAX_KEY_LENGTH];
78                 char *ip=loc_iv,*kp=loc_key;
79                 int i;
80                 memset(loc_iv,0,EVP_MAX_IV_LENGTH);
81                 memset(loc_key,0,EVP_MAX_KEY_LENGTH);
82         CODE:
83                 i=key.dsize;
84                 if (key.dsize > EVP_CIPHER_CTX_key_length(ctx))
85                         i=EVP_CIPHER_CTX_key_length(ctx);
86                 if (i > 0)
87                         {
88                         memset(kp,0,EVP_MAX_KEY_LENGTH);
89                         memcpy(kp,key.dptr,i);
90                         }
91                 else
92                         kp=NULL;
93                 i=iv.dsize;
94                 if (iv.dsize > EVP_CIPHER_CTX_iv_length(ctx))
95                         i=EVP_CIPHER_CTX_iv_length(ctx);
96                 if (i > 0)
97                         {
98                         memcpy(ip,iv.dptr,i);
99                         memset(ip,0,EVP_MAX_IV_LENGTH);
100                         }
101                 else
102                         ip=NULL;
103                 EVP_CipherInit(ctx,EVP_CIPHER_CTX_cipher(ctx),kp,ip,enc);
104                 memset(loc_key,0,sizeof(loc_key));
105                 memset(loc_iv,0,sizeof(loc_iv));
106
107 SV *
108 p5_EVP_C_cipher(ctx,in)
109         EVP_CIPHER_CTX *ctx;
110         datum in;
111         CODE:
112                 RETVAL=newSVpv("",0);
113                 SvGROW(RETVAL,in.dsize+EVP_CIPHER_CTX_block_size(ctx)+1);
114                 EVP_Cipher(ctx,SvPV(RETVAL,na),in.dptr,in.dsize);
115                 SvCUR_set(RETVAL,in.dsize);
116         OUTPUT:
117                 RETVAL
118
119 SV *
120 p5_EVP_C_update(ctx, in)
121         EVP_CIPHER_CTX *ctx
122         datum in
123         PREINIT:
124         int i;
125         CODE:
126                 RETVAL=newSVpv("",0);
127                 SvGROW(RETVAL,in.dsize+EVP_CIPHER_CTX_block_size(ctx)+1);
128                 EVP_CipherUpdate(ctx,SvPV(RETVAL,na),&i,in.dptr,in.dsize);
129                 SvCUR_set(RETVAL,i);
130         OUTPUT:
131                 RETVAL
132
133 SV *
134 p5_EVP_C_final(ctx)
135         EVP_CIPHER_CTX *ctx
136         PREINIT:
137         int i;
138         CODE:
139                 RETVAL=newSVpv("",0);
140                 SvGROW(RETVAL,EVP_CIPHER_CTX_block_size(ctx)+1);
141                 if (!EVP_CipherFinal(ctx,SvPV(RETVAL,na),&i))
142                         sv_setpv(RETVAL,"BAD DECODE");
143                 else
144                         SvCUR_set(RETVAL,i);
145         OUTPUT:
146                 RETVAL
147
148 void
149 p5_EVP_C_DESTROY(ctx)
150         EVP_CIPHER_CTX *ctx
151         CODE:
152         free((char *)ctx);
153