I'm trying to encrypt a message using the ECDSA algorithm with OpenSSL (1.1.1), but I must be doing something wrong with my pointers, because everytime I run the code, it gives me a different result.
Here's what I do:
create a key using custom curve parameters (with BN_hex2bn);
sign a simple message using ECDSA_do_sign;
split the message into the R and S points (ECDSA_SIG_get0_r and ECDSA_SIG_get0_s);
display the resulting R point.
And the display value is always different, while I expect it to be the same (because same message and same key). I think some memory is deallocated somewhere, giving me a pointer to invalid data, but I'm not sure about it; I have checked:
the keys are ok, and they are valid according to EC_KEY_check_key;
the two variables s and r are already wrong, hence it doesn't come from BN_bn2bin.
Here is my code if you want to give a try:
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/ecdsa.h>
#include <openssl/buffer.h>
int main(void) {
ECDSA_SIG *sig;
EC_KEY *eckey;
BIGNUM *priv_key = BN_new();
BIGNUM *x_key = BN_new();
BIGNUM *y_key = BN_new();
const char digest[] = "Hello, world!";
eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
// Set predefined keys
BN_hex2bn(&priv_key, "8e9b109e719098bf980487df1f5d77e9cb29606ebed2263b5f57c213df84f4b2");
BN_hex2bn(&x_key, "7fcdce2770f6c45d4183cbee6fdb4b7b580733357be9ef13bacf6e3c7bd15445");
BN_hex2bn(&y_key, "c7f144cd1bbd9b7e872cdfedb9eeb9f4b3695d6ea90b24ad8a4623288588e5ad");
EC_KEY_set_private_key(eckey, priv_key);
EC_KEY_set_public_key_affine_coordinates(eckey, x_key, y_key);
sig = ECDSA_do_sign(digest, 32, eckey);
// Get the resulting point
const BIGNUM *r = ECDSA_SIG_get0_r(sig);
const BIGNUM *s = ECDSA_SIG_get0_s(sig);
unsigned char rc[256];
unsigned char sc[256];
BN_bn2bin(r, rc);
BN_bn2bin(s, sc);
// Print the result: some memory problem...
for(int i = 0; rc[i] != 0; i++) {
printf("%d ", rc[i]);
}
return 0;
}
Do no forget to link the libraries when you compile it: gcc -g -o main main.c -lssl -lcrypto.
Related
I am trying to make a CUPS print system. I want to get printer status, how many pages printed sofar etc.
To do that, I am executing example programs given in CUPS examples.
#include <cups/cups.h>
#include <stdio.h>
int main(){
int num_options;
cups_option_t *options;
cups_dest_t *dests;
int num_dests = cupsGetDests(&dests);
cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
int job_id;
/* Print a single file */
job_id = cupsPrintFile(dest->name, "testfile.txt", "Test Print", num_options, options);
cupsFreeDests(num_dests, dests);
return 0;
}
I compile it using gcc myfile.c -o myout -lcups
When I try to execute ./myout
I am getting
Segmentation fault
I am using Raspberry-pi 3 board as my CUPS server.
Thanks in advance.
dest is pointing to non-valid address.
cups_dest_t *dest; // declared but not initialized or assigned afterwards
So dereferencing it ( cupsPrintFile(dest->name... ) is UB and can cause SegFault.
This is how you should have used it (taken from here):
#include <cups/cups.h>
cups_dest_t *dests;
int num_dests = cupsGetDests(&dests);
cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
/* do something with dest */
cupsFreeDests(num_dests, dests);
Update:
Your code doesn't handle some of the variables (i.e. leaves them uninitialized - bad). The first one I see is cups_option_t *options;. Take care of all of your variables, and if that's not working - debug.
int main(){
int num_options;
cups_option_t *options; // add a call to "cupsAddOption("first", "value", num_options, &options);"
cups_dest_t *dests;
int num_dests = cupsGetDests(&dests);
cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
int job_id;
/* Print a single file */
job_id = cupsPrintFile(dest->name, "testfile.txt", "Test Print", num_options, options); // options is used here but is uninitialized
cupsFreeDests(num_dests, dests);
return 0;
}
I've got some code which generates an array of strings of different file names and then
passes them into a function to write some data to them. It adds a incrementing number to the starting filename which is supplied from an input argument.
The problem is that it works fine running from source in Visual Studio 2012 but when I compile it and run it as an .exe the program crashes.
The .exe doesn't appear to be passing the array of strings properly which is causing an error when it attempts to use the string
for opening a file etc.
Here is the isolated bit of code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <Windows.h>
void processing_function(int num_output, char **outnames)
{
/* in Visual Studio this works fine and prints all
the names correctly. Running from .exe will crash */
for(int idx = 0; idx <num_output;idx++)
{
printf("outnames[%d] is %s\n",idx,outnames[idx]);
}
}
int main(int argc, char *argv[])
{
/*nframes comes from another function, outname comes from input arguement */
int num_output = ceil(((double)*nframes / 1100));
int outname_len = strlen(outname)+1;
char *out_right;
out_right = (char*) malloc(sizeof(char)*outname_len);
/*Split string to append numbers before file extension */
strcpy(out_right,outname);
strrev(out_right);
strtok(out_right,".");
strcat(out_right,".");
strrev(out_right);
int out_right_len = strlen(out_right);
strtok(outname,".");
strcat(outname,"-");
int out_origlen = strlen(outname);
int num_len = 1;
char **outnames;
char *num;
char *outname_tmp;
outnames = (char**) malloc(sizeof(char)*(num_output));
int out_len;
double dbl_idx;
int *numfs = (int*)malloc(sizeof(int)*num_output);
for(int idx = 1;idx <num_output+1;idx++)
{
/*convert output number to string and stitch complete name back together and place into array */
num_len = ceil(log10((double)idx+0.1));
num = (char*) malloc(sizeof(char)*(num_len+1));
outname_tmp = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outname_tmp,outname);
sprintf(num,"%d",idx);
strcat(outname_tmp,num);
free(num);
strcat(outname_tmp,out_right);
outnames[idx-1] = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outnames[idx-1],outname_tmp);
free(outname_tmp);
printf("%s\n",outnames[idx-1]);
}
free(out_right);
processing_function(num_ouput, outnames)
return(0);
}
EDIT: Changed num_input to num_output as they do have the same value.
Running from .exe will sometimes start printing some of the names and then crash, opening the
debugger gives an error within output.c, with an access reading violation. I tried putting this code at
the top of the processing_function but that gave further problems downstream (heap corruption), which makes me think that the
code is messing up the memory but I can't see whats wrong with it, nor why it would work in VS but not as a .exe.
I could try and dodge the issue by generating the next output name on the fly every time it requires one but I'd really rather know why this isn't working.
Any help would be greatly appreciated.
I am going to take a shot and say, you passed num_input to processing_function() with outnames, outnames was allocated with num_output for size, but num_input and num_output have different values at runtime. So that lets processing_function() access out of bounds.
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#define RSA_LEN 2048
#define RSA_FACTOR 65537
int genRSA2048(unsigned char **pub,unsigned int *pub_l,unsigned char **priv,unsigned int *priv_l){
RSA *pRSA = NULL;
pRSA = RSA_generate_key(RSA_LEN,RSA_FACTOR,NULL,NULL);
if (pRSA){
pub_l = malloc(sizeof(pub_l));
*pub_l = i2d_RSAPublicKey(pRSA,pub);
priv_l = malloc(sizeof(priv_l));
*priv_l = i2d_RSAPrivateKey(pRSA,priv);
return 0;
} else {
return 1;
}
}
int main(){
unsigned char *pub = NULL;
unsigned int publ;
unsigned char *priv = NULL;
unsigned int privl;
genRSA2048(&pub,&publ,&priv,&privl);
RSA *privrsa = NULL;
d2i_RSAPrivateKey(&privrsa,(const unsigned char **)&priv,privl);
RSA *pubrsa = NULL;
d2i_RSAPublicKey(&pubrsa,(const unsigned char **)&pub,publ);
unsigned char * data ="01234567890123456789012345678912";
unsigned char encrypted[256];
unsigned char decrypted[32];
int len = RSA_private_encrypt(32,data,encrypted,privrsa,RSA_PKCS1_PADDING);
RSA_public_decrypt(len,encrypted,decrypted,pubrsa,RSA_PKCS1_PADDING);
}
I've tried to find the bug by checking with gdb but as being fairly new to C I haven't find any clue to tell me what is happening but I believe it's an allocation problem, however according to the d2i_RSAPrivateKey and similar, they're supposed to allocate the space by itself.
Any help would be greatly appreciated.
compiled as cc foo.c -lcrypto
This is the follow up of this question:
Generate RSA public/private key with OpenSSL?
As I reference I used #WhozCraig example in the comments, which can be found here, even when it's quite different, it was a lot of help.
http://coliru.stacked-crooked.com/a/ae64a70076436165
pub_l = malloc(sizeof(pub_l)); is simply not needed. Nor is priv_l = malloc(sizeof(priv_l));. Remove them both from your function.
You should be populating your out-parameters; instead you're throwing out the caller's provided addresses to populate and (a) populating your own, then (b) leaking the memory you just allocated.
The result is the caller's privl and publ are untouched and thus the decoding back to RSA is dysfunctional, as both values are indeterminate.
pRSA = RSA_generate_key(RSA_LEN,RSA_FACTOR,NULL,NULL);
I think this is wrong. I know you are supposed to use RSA_generate_key_ex, and I think it needs a BIGNUM, not an integer. You should have gotten a warning. See RSA_generate_key(3) for details.
Your code should look something like:
BIGNUM* exp = BN_new();
ASSERT(exp != NULL);
int rc = BN_set_word(exp, RSA_F4);
ASSERT(rc == 1);
RSA* rsa = RSA_new();
ASSERT(rsa != NULL);
rc = RSA_generate_key_ex(rsa, 2048, exp, NULL);
ASSERT(rc == 1);
Be sure to call BN_free on the BIGNUM, and RSA_free on the RSA pointer.
RSA *privrsa = NULL;
d2i_RSAPrivateKey(&privrsa,(const unsigned char **)&priv,privl);
RSA *pubrsa = NULL;
d2i_RSAPublicKey(&pubrsa,(const unsigned char **)&pub,publ);
For this, it looks like you are trying to separate the public key and private key. For that, use RSAPublicKey_dup and RSAPrivateKey_dup. See Separating public and private keys from RSA keypair variable.
Its not clear to me what you are trying to do with the following. You should state what you are trying to do...
pub_l = malloc(sizeof(pub_l));
*pub_l = i2d_RSAPublicKey(pRSA,pub);
priv_l = malloc(sizeof(priv_l));
*priv_l = i2d_RSAPrivateKey(pRSA,priv);
I'm just guessing, but I'm going to say its all wrong. sizeof(priv_l) is the size of a pointer, so its 4 or 8 bytes. You're also overwriting the pointer passed in by the caller...
Also see OpenSSL's rsautl cannot load public key created with PEM_write_RSAPublicKey. It talks about saving the keys with SubjectPublicKeyInfo and PrivateKeyInfo in both ASN.1/DER and PEM formats.
By writing the {Public|Private}KeyInfo, the OID gets written to the key. That's important for interop. You also use the RSA* (and even an EVP_PKEY*), and not byte arrays.
I've written a function that determines whether or not to assign default values (it assigns default values if the flag is not present, and it assigns values the user passes if the flag is present). And I'm trying to test my function with a string to see if it did give me the right numbers. I keep getting "Segmentation Fault" when I try to run the tests, it compiles, but the tests just don't work. :(
Here's my header file:
#ifndef COMMANDLINE_H
#define COMMANDLINE_H
#include "data.h"
#include <stdio.h>
struct point eye;
/* The variable listed above is a global variable */
void eye_flag(int arg_list, char *array[]);
#endif
Here's my implementation file:
#include <stdio.h>
#include "commandline.h"
#include "data.h"
#include "string.h"
/* Used global variables for struct point eye */
void eye_flag(int arg_list, char *array[])
{
eye.x = 0.0;
eye.y = 0.0;
eye.z = -14.0;
/* The values listed above for struct point eye are the default values. */
for (int i = 0; i <= arg_list; i++)
{
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
}
And here are my test cases:
#include "commandline.h"
#include "checkit.h"
#include <stdio.h>
void eye_tests(void)
{
char *arg_eye[6] = {"a.out", "sphere.in.txt", "-eye", "2.4", "3.5", "6.7"};
eye_flag(6, arg_eye);
checkit_double(eye.x, 2.4);
checkit_double(eye.y, 3.5);
checkit_double(eye.z, 6.7);
char *arg_eye2[2] = {"a.out", "sphere.in.txt"};
eye_flag(2, arg_eye2);
checkit_double(eye.x, 0.0);
checkit_double(eye.y, 0.0);
checkit_double(eye.z, -14.0);
}
int main()
{
eye_tests();
return 0;
}
The absolute easiest way to solve this one is run it in a debugger. You probably won't even need to learn how to step through your code or anything - just fire up, run, and read the line.
If you are on a *nix system:
Compile your code with -g flag.
Load as, e.g. gdb a.out.
Run now that it's loaded - (gdb) run.
Do whatever you need to reproduce the segfault.
bt or where should give you a stack trace - and an exact line that is causing your problem.
I'm sure enough you can solve it from there to post this as an answer; but if not, knowing the exact line will make it very much easier to research and solve.
The errors are here:
for (int i = 0; i <= arg_list; i++)
{ ///^^
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
//^^^
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
i <= arg_list is wrong since you pass in 6, array index starts from 0, the max value is 5
i+1, i+2,i+3 will give you out of bounds index when you iterate from 0 to 5.
Your loop condition is wrong. It should be i < arg_list.
Think about what happens when i == arg_list.
Im working on a server in C that dynamically generating Lua commands on the fly and send them by socket to the clients. Right now the server is using plain text, but I would like the server to pre-compile the script before sending it to the clients.
I check luac.c but couldn't find how to be able to do something like this:
char lua_commands[ 1024 ] = { "a = 123; b = 456; c = a + b;" };
int socket
unsigned int send_buffer_size
unsigned char *send_buffer
/* Compile lua_commands and store the binary script into send_buffer without
having to write first the .out on disk then read it again in order store the content
into send_buffer */
send( socket, send_buffer, send_buffer_size, 0 );
Anybody can help me to achieve this?
[ Update ]
Ok, I think I figure it out:
#include "lua.h"
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
static int writer( lua_State *L, const void *p, size_t size, void *u ){
unsigned int i = 0;
unsigned char *d = ( unsigned char * )p;
// Print all the bytes on the console.
while( i != size ) {
printf("%d ", d[ i ] );
++i;
}
return 0;
}
void compile( lua_State *L, char *command ){
const Proto* f;
if (luaL_loadstring( L, command ) !=0 ) {
printf( "%s\n", lua_tostring( L, -1 ) );
}
f = toproto( L,-1 );
lua_lock( L );
luaU_dump( L, f, writer, NULL, 1 );
lua_unlock( L );
}
int main (int argc, const char * argv[]) {
lua_State *L = lua_open();
compile( L, "a = 123; b = 456; c = a + b; print( c );" );
lua_close( L );
return 0;
}
However that leads me to another question, do I have to close and reopen (lua_open, lua_close) the Lua state every time I'm calling my compile() function with other Lua commands or the output will only be the result of the latest luaL_loadstring?
Im not sure but look to me from the toproto macro definition that the top most stack will be returned am I correct?
You should use lua_dump() instead of internal toproto() + luaU_dump() functions. As an added bonus, this way your code will support LuaJIT 2.
It is not necessary to recreate the state each time you get the dump.
BUT. I would avoid executing Lua bytecode that came from the untrusted source (and server often is untrusted to the client). It is not safe, and may lead to severe security issues. (No such problems with source code — but you still have to sandbox it, of course.)
In general, always make sure that you check that the code you load from untrusted source is not bytecode (it is, if first byte is 27 decimal). Always execute such code in a sandbox.
If all that you need is to pass data in Lua-friendly way, pick some proper data serialization library instead. Aside of sandboxing and portability problems, loadstring() is rather slow.
For example, we're using using my luatexts library for similar purposes (make sure to pore through this list for alternatives). Luatexts supports tuples, which plays nicely with function calls. For example (in pseudocode):
Server:
my_send(luatexts.lua.save("myMethod", { param = true }, 42))
Client:
local actions = { }
function actions.myMethod(params, number)
print(params.param, number) --> true, 42
end
local function handle_action(ok, name, ...)
assert(ok, name) -- name would contain error message if not OK
local handler = assert(actions[name], "unknown action")
return handler(...)
end
local str = my_receive()
handle_action(luatexts.load(str))
Open a ticket if you want luatexts.save or streaming support implemented in C.