Libssh2 with WinCNG unable to obtain public key from private key with passphrase - private-key

I'm using libssh2 with WinCNG. It is failing to extract public key from a private key + passphrase pair. I see in wincng.c
_libssh2_wincng_load_pem(LIBSSH2_SESSION *session,
const char *filename,
const char *passphrase,
const char *headerbegin,
const char *headerend,
unsigned char **data,
unsigned int *datalen)
{
FILE *fp;
int ret;
(void)passphrase;
fp = fopen(filename, "r");
if (!fp) {
return -1;
}
ret = _libssh2_pem_parse(session, headerbegin, headerend,
fp, data, datalen);
fclose(fp);
return ret;
}
passphrase is no where used when private key file is read.
Is it possible to use a private key + passphrase pair to extract publick key using libssh2 WinCNG?
Thanks in advance

Related

How to retrieve an int array that is stored in a table using PROGMEM?

I'm new to Arduino and currently learn to use PROGMEM to store variables so that I can save dynamic memory. I have 13 variables including these three below that I store using PROGMEM.
Here are some of example of variables that I store and use it in my functions :-
const unsigned int raw_0[62] PROGMEM = {2600,850,400,500,400,500,450,850,450,850,1350,850,450,450,400,500,400,450,450,400,450,450,450,450,400,450,900,850,900,850,900,450,450,850,900,850,900,850,450,450,900,450,400,450,400,900,450,450,450,400,450,450,450,450,400,450,450,450,450,400,450,};
const unsigned int raw_1[60] PROGMEM = {2600,850,450,450,450,450,450,850,450,850,1350,850,500,400,450,400,450,450,450,450,400,450,450,450,400,450,900,850,900,900,850,450,450,850,850,900,900,900,400,450,900,450,450,400,450,850,450,450,450,450,400,450,450,450,450,400,450,450,850,};
const unsigned int raw_a[100] PROGMEM = {3500,1700,400,450,450,1250,450,400,450,400,450,400,500,400,450,400,450,400,450,400,450,450,400,400,500,400,450,400,450,1300,400,450,450,400,450,400,450,400,450,400,450,400,500,350,500,400,450,400,450,1300,400,400,500,400,450,400,450,400,450,450,400,450,450,400,450,400,450,400,450,400,450,450,400,450,450,400,450,1250,450,400,450,400,500,400,450,400,450,400,450,400,450,400,450,1300,450,400,450,1250,450,};
Here is the table that store the variables. I learn this approach from Arduino website; https://www.arduino.cc/en/Reference/PROGMEM .
const unsigned int* const myTable[13] PROGMEM = {
raw_0,
raw_1,
raw_2,
raw_3,
raw_4,
raw_5,
raw_6,
raw_7,
raw_8,
raw_9,
raw_a,
raw_b,
raw_c};
My problem is, how do I retrieve these variables using PROGMEM such as raw_1 and raw_a ?
This is what I did but it did not work :-
unsigned int * ptr = (unsigned int *) pgm_read_word (&myTable [1]);
irsend.sendRaw(ptr,62,38);
Most of examples that I found, they use String or char datatype but in my case, I use array integer.
The ptr is also pointer to PROGMEM, so you have to read the value (or values in this case) by pgm_read_word. The IR library doesn't support that at all (I hope it's the correct one).
Anyway sendRaw implementation is this:
void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz)
{
// Set IR carrier frequency
enableIROut(hz);
for (unsigned int i = 0; i < len; i++) {
if (i & 1) space(buf[i]) ;
else mark (buf[i]) ;
}
space(0); // Always end with the LED off
}
And all used methods are public, so you can implement your own function to do the same:
void mySendRaw (IRsend & dev, const unsigned int buf[], unsigned int len, unsigned int khz)
{
// Set IR carrier frequency
dev.devenableIROut(khz);
for (unsigned int i = 0; i < len; i++) {
if (i & 1) dev.space(pgm_read_word(buf+i));
else dev.mark (pgm_read_word(buf+i));
}
dev.space(0); // Always end with the LED off
}
// And usage:
mySendRaw(irsend, (const uint16_t*)pgm_read_word(myTable+1), 62, 38);
However the size of arrays should be stored somewhere too, so you can use something like:
byte cmd = 1;
mySendRaw(irsend, (const uint16_t*)pgm_read_word(myTable+cmd), pgm_read_word(myTableLenghts+cmd), 38);

Arduino YUN Rest Api HTTP Post

I use Arduino YUN for IoT project.
I have a web service which requires headers and bodies, and I want to post data from arduino.
Default HttpClient library supports put, get and delete methods but doesn't support post method.
Any suggestion would be great. Thanks.
You can use the Process class to send the POST via curl (which is a part of OpenWRT on Arduino YÚN).
Example from http://starter-kit.nettigo.eu/2014/arduino-yun-sending-data-thingspeak-post/:
void postToThingSpeak(String key, float value[]) {
Process p;
String cmd = "curl --data \"key="+key;
for (int i=0;i<ARRAY_SIZE;i++) {
cmd = cmd + "&field"+ (i+1) + "=" + value[i];
}
cmd = cmd + "\" http://api.thingspeak.com/update";
p.runShellCommand(cmd);
Console.println(cmd);
p.close();
}
Maybe you have an old version of the Bridge library. The code I am seeing in HttpClient.h supports POST (version 1.6.3):
unsigned int get(String &url);
unsigned int get(const char * url);
void getAsynchronously(String &url);
void getAsynchronously(const char * url);
unsigned int post(String &url, String &data);
unsigned int post(const char * url, const char * data);
void postAsynchronously(String &url, String &data);
void postAsynchronously(const char * url, const char * data);
unsigned int patch(String &url, String &data);
unsigned int patch(const char * url, const char * data);
void patchAsynchronously(String &url, String &data);
void patchAsynchronously(const char * url, const char * data);
unsigned int put(String &url, String &data);
unsigned int put(const char * url, const char * data);
void putAsynchronously(String &url, String &data);
void putAsynchronously(const char * url, const char * data);
void setHeader(String &header);
void setHeader(const char * header);
boolean ready();
unsigned int getResult();
void noCheckSSL();
void checkSSL();

FFI Encryption/Decryption with LuaJit

I'm trying to encrypt and decrypt using OpenSSL through FFI in LuaJIT - I've tried a lot of different variations but I'm not having a lot of luck. My code seems to return empty strings all the time.
I'm attempting to following the pattern described as part of the OpenSSL docs: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_decrypt.html
local ffi = require "ffi"
ffi.cdef[[
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
void *malloc(size_t size);
void free(void *ptr);
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);
]]
local s = "hello world"
local s_len = #s
local out_len1 = ffi.new("size_t[1]")
local ctx = ffi.C.EVP_PKEY_CTX_new(gen_key, nil)
if not ctx then
return nil
end
if ffi.C.EVP_PKEY_encrypt_init(ctx) == 0 then
return nil
end
if ffi.C.EVP_PKEY_encrypt(ctx, nil, out_len1, s, s_len) == 0 then
return nil
end
local buf = ffi.new("unsigned char[?]", out_len1[0])
if ffi.C.EVP_PKEY_encrypt(ctx, buf, out_len1, s, s_len) == 0 then
return nil
end
local s = ffi.string(buf, out_len1[0])
local s_len = #s
local out_len2 = ffi.new("size_t[1]")
if ffi.C.EVP_PKEY_decrypt_init(ctx) == 0 then
return nil
end
if ffi.C.EVP_PKEY_decrypt(ctx, nil, out_len2, s, s_len) == 0 then
return nil
end
local buf = ffi.new("unsigned char[?]", out_len2[0])
if ffi.C.EVP_PKEY_decrypt(ctx, buf, out_len2, s, s_len) == 0 then
return nil
end
return ffi.string(buf, out_len2[0])
I think your code has missing declarations for certain types such as EVP_PKEY_CTX, EVP_PKEY, etc. You would need to add the definition of those data types as well. Basically, ffi.cdef defines all function names that are going to be used through the FFI, so LuaJIT can parse them.
On the other hand, the call to those functions should be made through a library that actually implement those functions, such as OpenSSL, not ffi.C. The C namespace is used to access libc plus other C libraries such as libm and libdl. Example:
local ffi = require("ffi")
local ssl = ffi.load("ssl")
ffi.cdef[[
struct evp_pkey_ctx_st {
};
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
struct evp_pkey_st {
};
typedef struct evp_pkey_st EVP_PKEY;
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *key, void *b);
]]
local ctx = ssl.EVP_PKEY_CTX_new(gen_key, nil)
if ctx then
print("ctx created")
else
return nil
end
Answering my own question.
My original code did not strictly follow the C implementation example from OpenSSL since it only ever got the length of the encrypted data. It also never used any padding, it reused variables and wasn't split into methods and it was intentionally missing some dependancies to hide some implementation details.
The following code now works (standalone) and is better structured but it intentionally does no error checking and also will struggle with content longer than (KeyLength - 42).
To give some context this code is expecting Certificates and Keys in PEM format:
local ffi = require "ffi"
local ssl = ffi.load "ssl"
ffi.cdef[[
typedef struct bio_st BIO;
typedef struct bio_method_st BIO_METHOD;
BIO *BIO_new(BIO_METHOD *type);
BIO *BIO_new_mem_buf(void *buf, int len);
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
typedef struct evp_pkey_st EVP_PKEY;
typedef struct engine_st ENGINE;
EVP_PKEY *EVP_PKEY_new(void);
void EVP_PKEY_free(EVP_PKEY *key);
typedef struct rsa_st RSA;
typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
RSA * PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, void *u);
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,RSA *key);
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2);
typedef struct x509_st X509;
X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
EVP_PKEY * X509_get_pubkey(X509 *x);
void X509_free(X509 *a);
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);
]]
function encrypt(publicPEM, body)
local bioIn = ffi.new("unsigned char[?]", #publicPEM)
ffi.copy(bioIn, publicPEM, #publicPEM)
local bio = ffi.C.BIO_new_mem_buf(bioIn, -1)
local x509 = ffi.C.PEM_read_bio_X509(bio, nil, nil, nil)
ffi.gc(x509, ffi.C.X509_free)
local pKey = ffi.C.X509_get_pubkey(x509)
local ctx = ffi.C.EVP_PKEY_CTX_new(pKey, nil)
ffi.C.EVP_PKEY_encrypt_init(ctx)
-- Adds OEAP padding
ffi.C.EVP_PKEY_CTX_ctrl(ctx, 6, -1, 4097, 4, null)
-- Get the length
local outputLength = ffi.new("size_t[1]")
ffi.C.EVP_PKEY_encrypt(ctx, nil, outputLength, body, #body)
-- Encrypt into outputBuffer
local outputBuffer = ffi.new("unsigned char[?]", outputLength[0])
ffi.C.EVP_PKEY_encrypt(ctx, outputBuffer, outputLength, body, #body)
-- Turn it into a string
return ffi.string(outputBuffer, outputLength[0])
end
function decrypt(privatePEM, body)
local bioIn = ffi.new("unsigned char[?]", #privatePEM)
ffi.copy(bioIn, privatePEM, #privatePEM)
local bio = ffi.C.BIO_new_mem_buf(bioIn, -1)
if not bio then
return nil
end
local rsa = ffi.C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, nil)
local pKey = ffi.C.EVP_PKEY_new()
ffi.C.EVP_PKEY_set1_RSA(pKey, rsa)
ctx = ffi.C.EVP_PKEY_CTX_new(pKey, nil)
ffi.C.EVP_PKEY_decrypt_init(ctx)
-- Adds OEAP padding
ffi.C.EVP_PKEY_CTX_ctrl(ctx, 6, -1, 4097, 4, null)
-- Get the length
local outputLength = ffi.new("size_t[1]")
ffi.C.EVP_PKEY_decrypt(ctx, nil, outputLength, body, #body)
-- Decrypt into outputBuffer
local outputBuffer = ffi.new("unsigned char[?]", outputLength[0])
ffi.C.EVP_PKEY_decrypt(ctx, outputBuffer, outputLength, body, #body)
-- Turn it into a string
return ffi.string(outputBuffer, outputLength[0])
end
io.write("Result: "..tostring(decrypt([[-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCoOeFfldK3bcsun1klFb+d3egSKkfq3oFAf6n6hQ2R3TrzY3Bb
+4hYSr5LhrP/HYOvc7bxk+T3GQe6C8B/7aOYJQ+DOweKoNK90uVEQRtFO8EZ4Z7r
JfaS2rhPuX71AnfwuvNG/TZ5UFruvwUqvs2hzw57gl+IzFgAtG8rtVX/zwIDAQAB
AoGAEeGFGRndue2LqTr6yLxVD7ykjDm+RzK7XlWzhZNa6+Qt/ezV5pEH3wqiy3hX
7Yf/lUiha3Ai6Dja32WcYnyp5Lf9vvxMcdyMlv3r78N7KUccXo6qvh0dE5VdrNxH
4U5oDs5U4OXaTC3/pCgBCV9w7IxbrLvsj1yKYQ7QBOLnJTECQQDQuHo6e1C2miyI
VZv5YzTdXucpshAhpDNf65Z214e/Ww1OOFNOw9sBaGGyOVv+F9EfHC8kO4pA32S7
HOx+knRlAkEAzlUpafetWL+Ht6yguyc9yBbfeoFL6v576GpMjkIV7w1oqmiDa5ep
P71U1evgYAwH6X0ZcnPXZwZU7eOkBZdeIwJBAKG2nPUcwC+KioBjHAMAa2As/Jug
m8EE8M0bwit32HRZfpihKWK4esG/dxpYOL9JArzA4IGJJBgZPXl/8ngqzsUCQQCy
Z1xJrcgKxoC4xeCsMf/vdCeDKyzTYXsNuGu9TVLdwcBQJ9IKQ7Yp0LD7ztnQ8lYd
AvfvyE3lXMoubvgxhXH1AkBDTjC3cHtlXygZcrqviIq/lOblm2voR2YW520079Yd
h0u2xcG80J53NkBk/q0IaTOamESi1IrD2ds3xp5mZulI
-----END RSA PRIVATE KEY-----
]], encrypt([[-----BEGIN CERTIFICATE-----
MIICYTCCAcoCCQCT+Ubn23B63TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV
UzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEN
MAsGA1UEChMES29uZzEWMBQGA1UECxMNSVQgRGVwYXJ0bWVudDESMBAGA1UEAxMJ
bG9jYWxob3N0MB4XDTE2MDExODEwNDUyOVoXDTE3MDExNzEwNDUyOVowdTELMAkG
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFu
Y2lzY28xDTALBgNVBAoTBEtvbmcxFjAUBgNVBAsTDUlUIERlcGFydG1lbnQxEjAQ
BgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqDnh
X5XSt23LLp9ZJRW/nd3oEipH6t6BQH+p+oUNkd0682NwW/uIWEq+S4az/x2Dr3O2
8ZPk9xkHugvAf+2jmCUPgzsHiqDSvdLlREEbRTvBGeGe6yX2ktq4T7l+9QJ38Lrz
Rv02eVBa7r8FKr7Noc8Oe4JfiMxYALRvK7VV/88CAwEAATANBgkqhkiG9w0BAQUF
AAOBgQAEC5ugqY6rOd3BbIam172OVQQwxcVx8BVfuiqX0zsFdBwTm/AvvdyJXRwo
64AqEIanvJF8Htq3Q9As6PNgHJ4eWEAZYTKlsf0PRM+d1T/uce3HY2SePuwr1Kqx
gFQjYTabjv361j8X3zB3HwrGsuED2UXxerXczszyiQNv/6BQlg==
-----END CERTIFICATE-----
]], "hello world"))).."\n")

How to create a Queue of unsigned char array in Qt?

I am new in Queue (FIFO) and Qt. I want to create a Queue of unsigned char array in Qt. How to do it? Please help
unsigned char buffer[1024];
If you want to use the Qt API, then you can use the QQueue class -
QQueue<unsigned char> queue;
queue.enqueue(65);
queue.enqueue(66);
queue.enqueue(67);
while (!queue.isEmpty())
cout << queue.dequeue() << endl;
If you want to build the queue on your own, then I guess you can declare a Queue class like this -
class Queue
{
private:
enum{SIZE=1024, EMPTY=0};
unsigned char buffer[SIZE];
int readHead, writeHead;
public:
Queue()
{
readHead = writeHead = EMPTY;
}
void push(unsigned char data);
unsigned char pop();
unsigned char peek();
bool isEmpty();
};
void Queue::push(unsigned char data)
{
if((readHead - writeHead) >= SIZE)
{
// You should handle Queue overflow the way you want here.
return;
}
buffer[writeHead++ % SIZE] = data;
}
unsigned char Queue::pop()
{
unsigned char item = peek();
readHead++;
return item;
}
unsigned char Queue::peek()
{
if(isEmpty())
{
// You should handle Queue underflow the way you want here.
return;
}
return buffer[readHead % SIZE];
}
bool Queue::isEmpty()
{
return (readHead == writeHead);
}
If you want to maintain a Queue of unsigned char array, then you will have to maintain a queue of unsigned char pointers -
QQueue<unsigned char *> queue;
unsigned char *array1 = new unsigned char[10]; // array of 10 items
array1[0] = 65;
array1[1] = 66;
queue.enqueue(array1);
unsigned char *array2 = new unsigned char[20]; // an array of 20 items
queue.enqueue(array2);
unsigned char *arr = queue.dequeue();
qDebug() << arr[0] << ", " << arr[1];
Note: You should take care of the memory cleanup after you are done with this queue. IMHO, you better avoid this type of design though.

QByteArray convert to/from unsigned char *

QByteArray inArray = " ... ";
unsigned char *in = convert1(inArray);
unsigned char *out;
someFunction(in, out);
QByteArray outArray = convert2(out);
the question is how can I correctly make these conversions (convert1 and convert2).
I cannot change someFunction(unsigned char *, unsigned char *), but I have to work with QByteArray here.
Qt has really great docs, you should use them.
If someFunction doesn't modify or store pointer to in data you can use this:
QByteArray inArray = " ... ";
unsigned char *out;
someFunction((unsigned char*)(inArray.data()), out);
QByteArray outArray((char*)out);
Otherwise you have to make a deep copy of the char* returned by QByteArray::data() (see the docs for code snippet).
if someFunction takes a const char* args then just use ConstData() or data() in QByteArray class.
if you need a char*, you can then use strdup(). This method is doing this
char *strdup (const char *s) {
char *d = malloc (strlen (s) + 1); // Space for length plus nul
if (d == NULL) return NULL; // No memory
strcpy (d,s); // Copy the characters
return d; // Return the new string
}
more info here: strdup() - what does it do in C?

Resources