looking for C w/openssl equivalent of java bouncycastle SHA256withRSA signing - c

ok ive been banging my head on this for over two days now. I need to code in c, using openssl library, the equivalent for the following java code :
byte[] result = null;
Signature st = Signature.getInstance(BC_PROV_ALGORITHM_SHA256RSA, "BC");
st.initSign(privateKey);
st.update(data);
result = st.sign();
return result;
The most obvious approach was this
RSA_sign( NID_sha256, ( const BYTE* ) pszMessage256Hash,
strlen( pszMessage256Hash), ( unsigned char *) pSignature,
&iSignLen, pPrivateMerchantKey )
Already checked that the key is the same and the content of the pszMessage256Hash is identical to the "data" variable from java. Due to padding the result is different every time however the server-side verification is rejecting the second signature.
Any help would be appreciated, as i said, i have been wasting way too much time on this.

Related

Iterating over an X509 certificate's subject elements and knowing the type

I'd like to iterate over the name entries in a connecting client's certificate and perform some logic.
I found the following example on this page:
X509_NAME *subj = X509_get_subject_name(cert);
for (int i = 0; i < X509_NAME_entry_count(subj); i++) {
X509_NAME_ENTRY *e = X509_NAME_get_entry(subj, i);
ASN1_STRING *d = X509_NAME_ENTRY_get_data(e);
char *str = ASN1_STRING_data(d);
}
As part of my logic I'd like to know which kind of X509_NAME_ENTRY I'm looking at (ideally by it's NID, for instance NID_commonName), but I can't figure out how to extract this information. From looking at OpenSSL's code I see that I can get the ASN1_OBJECT using X509_NAME_ENTRY_get_object, and that has a nid field in it, but it doesn't seem to be exposed so I can't just grab it with ->nid.
Is there any API function I'm missing to get this information?
Another example on this page is this one:
for (;;) {
int lastpos = X509_NAME_get_index_by_NID(subj, NID_commonName, lastpos);
if (lastpos == -1)
break;
X509_NAME_ENTRY *e = X509_NAME_get_entry(subj, lastpos);
/* Do something with e */
}
I'm considering using this approach instead, but I'm wondering if it's less efficient since I have several name entries I'd like to check, and instead of having one run through the subject I'll potentially be moving back and forth (and my server application needs to minimize connection time as much as possible).
To clarify, I don't just need the certificate's common name, I might need other parts of the certificate's subject (based on the server's configuration) so I'd like to be flexible but also go over the subject as cleanly as possible.

How do I read OpenVINO IR models from memory with the OpenVINO C API

I am having trouble reading OpenVINO IR networks (XML and bin) from memory using ie_core_read_network_from_memory() in the OpenVINO 2021.4 C API ie_c_api.h.
I suspect that I am creating the network weight blob wrong, but I cannot find any information on how to create weight blobs correctly for networks.
I have read the OpenVINO C API docs but cannot deduce from docs what I am doing wrong. The OpenVINO code repo contains some C code samples, but none of the samples seem to use ie_core_read_network_from_memory().
Below is a cut out of the code I am having trouble with.
// void* dmem->data - network memory buffer (float32)
// size_t dmem->size - size of network memory buffer (bytes)
ie_core_t* ov_core = NULL;
IEStatusCode status = ie_core_create("", &ov_core);
if (status != OK)
{
// error handling
}
const dimensions_t weights_tensor_dims =
{ 4, { 1, 1, 1, dmem->size/sizeof(float) } };
tensor_desc_t weights_tensor_desc = { OIHW, weights_tensor_dims, FP32 };
ie_blob_t* ov_model_weight_blob = NULL;
status = ie_blob_make_memory_from_preallocated(
&weights_tensor_desc, dmem->data, dmem->size, &ov_model_weight_blob);
if (status != OK)
{
// error handling
}
// char* model_xml_desc - the model's XML string
uint8_t* ov_model_xml_content = (uint8_t*)model_xml_desc;
ie_network_t* ov_network = NULL;
size_t xml_sz = strlen(ov_model_xml_content);
status = ie_core_read_network_from_memory(
ov_core, ov_model_xml_content, xml_sz, ov_model_weight_blob, &ov_network);
if (status != OK)
{
// Always get "GENERAL_ERROR (-1)"
}
The code works fine down to the ie_core_read_network_from_memory() call which results in "GENERAL_ERROR".
I have tried two models that were converted from Tensorflow. One is a simple [X] -> [Y] regression model (single input value, single output value). The other is also a regression model [X_1, X_2, ..., X_9] -> [Y] (nine input values, single output value). They work fine when reading them from file with ie_core_read_network(), but for my use case I must provide the network as a binary memory buffer and XML string.
I would appreciate any help, either by pointing out what I am getting wrong or directing me to some code samples that use ie_core_read_network_from_memory().
System information:
Windows 10
OpenVINO v2021.4.689
Microsoft Visual Studio 2019
UPDATE: An Intel employee reached out to me in another forum and pointed out that there is a unit test for ie_core_read_network_from_memory(). The unit test successfully reads a network from memory and made clear that I was in fact using a faulty tensor description to produce the weight blob, just as I suspected. Apparently the weight blob descriptor should be one dimensional, have memory layout ANY and datatype U8 even though the model weights are fp32.
From the unit test:
std::string bin_std = TestDataHelpers::generate_model_path("test_model", "test_model_fp32.bin");
const char* bin = bin_std.c_str();
//...
std::vector<uint8_t> weights_content(content_from_file(bin, true));
tensor_desc_t weights_desc { ANY, { 1, { weights_content.size() } }, U8 };
However, simply changing the tensor descriptor was not enough to get my code to work so it remains for me to properly translate the C++ code from the unit test to my C environment before the issue to can be considered solved.
Thanks
Refer to tensor_desc struct and standard layout format.
Apart from that, it is recommended to use the Benchmark_app tool to test the inference performance.

AudioFileCreateWithURL failed('wht?')

I'm trying to record sound using Audio Queue, but every time I want to write to file I get the message AudioFileCreateWithURL failed('wht?'). I haven't been able to find a corresponding solution to this error, for I haven't found a similar (wht?) error elsewhere. I acquired the code from Apple's official guide for Audio Queue programming and it looks like this:
char* filePath = "Users/linus/voicies/output.wav";
CFURLRef myFileURL = CFURLCreateFromFileSystemRepresentation( // 1
NULL, // 2
(const UInt8 *) filePath, // 3
strlen (filePath), // 4
false // 5
);
OSStatus err = AudioFileCreateWithURL(
myFileURL,
kAudioFileWAVEType,
&recordFormat,
kAudioFileFlags_EraseFile,
&recorder.recordFile
);
CheckError(err);
in which CheckError finds the corresponding error, which is (wht?). I have no idea what that means and what I must do to make it happen, since the code I have used is almost identical to the sample codes. I appreciate any kind of clue.

How to call threadsafe rrd_update_r Round Robin Database function with C API?

Can anybody help me to find out how to call rrd_update_r function of the rrdtool c API from http://oss.oetiker.ch/rrdtool/index.en.html?
It was quite easy to call the non-threadsafe version of rrd_update, but this one is more tricky...
normal rrd_update:
char *updateparams[] = {
"rrdupdate",
rrd_file,
values,
NULL
};
rrd_clear_error();
result = rrd_update(3, updateparams); //argc is first arg
Because the programm has to run in a multithreaded environment I got several errors by not using the threadsafe functions!
But it is not so easy to use rrd_update_r, because it requires a template too...
int rrd_update_r(const char *filename, const char *_template,
int argc, const char **argv);
and I really have no idea how to create one...
char *updateparams[] = {
"rrdupdate",
rrd_file,
values,
NULL
};
rrd_clear_error();
result = rrd_update_r(rrd_file, NULL,3, updateparams);
does not work and produces the following error when executing it...
error: /var/tmp/rrds/1.rrd: expected timestamp not found in data source from rrdupdate
Hopefully someone can help me!
thx and br,
roegi
Well, looking at the source code...
It appears that rrd_update_r does not want to see the "rrupdate" argument. So try just passing rrd_file and values as a 2-element argv.
Actually the source for rrd_update is not hard to read; you can find it in src/rrd_update.c. And rrd_update_r appears to be a much lower-level function that rrd_update itself calls. So this may not actually fix your underlying problem.
Now it is working!
Nemo - thx for your help!
It was not exactly your solution but it was a hint to the right direction!
It works with:
/*
rrd_file is a char * to "/var/tmp/1.rrd"
NULL says not to use a template
1 --> argc
values is a char * to "N:value-1:value-2:.....:value-n"
*/
result = rrd_update_r(rrd_file, NULL, 1, (void *) &values);

Updated: When to "mortalize" a variable in Perl Inline::C

I am trying to wrap a C library into Perl. I have tinkered with XS but being unsuccessful I thought I should start simply with Inline::C. My question is on Mortalization. I have been reading perlguts as best as I am able, but am still confused. Do I need to call sv_2mortal on an SV* that is to be returned if I am not pushing it onto the stack?
(PS I really am working on a less than functional knowledge of C which is hurting me. I have a friend who knows C helping me, but he doesn't know any Perl).
I am providing a sample below. The function FLIGetLibVersion simply puts len characters of the library version onto char* ver. My question is will the version_return form of my C code leak memory?
N.B. any other comments on this code is welcomed.
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;
use Inline (
C => 'DATA',
LIBS => '-lm -lfli',
FORCE_BUILD => 1,
);
say version_stack();
say version_return();
__DATA__
__C__
#include <stdio.h>
#include "libfli.h"
void version_stack() {
Inline_Stack_Vars;
Inline_Stack_Reset;
size_t len = 50;
char ver[len];
FLIGetLibVersion(ver, len);
Inline_Stack_Push(sv_2mortal(newSVpv(ver,strlen(ver))));
Inline_Stack_Done;
}
SV* version_return() {
size_t len = 50;
char ver[len];
FLIGetLibVersion(ver, len);
SV* ret = newSVpv(ver, strlen(ver));
return ret;
}
Edit:
In an attempt to answer this myself, I tried changing the line to
SV* ret = sv_2mortal(newSVpv(ver, strlen(ver)));
and now when I run the script I get the same output that I did previously plus an extra warning. Here is the output:
Software Development Library for Linux 1.99
Software Development Library for Linux 1.99
Attempt to free unreferenced scalar: SV 0x2308aa8, Perl interpreter: 0x22cb010.
I imagine that this means that I don't need to mortalize in this case? I suspect that the error is saying that I marked for collection something that was already in line for collection. Can someone confirm for me that that is what that warning means?
I've been maintaining Set::Object for many years and had this question, too - perhaps best to look at the source of that code to see when stuff should be mortalised (github.com/samv/Set-Object). I know Set::Object has it right after many changes. I think though, it's whenever you're pushing the SV onto the return stack. Not sure how Inline changes all that.

Resources