Work with OpenSSL stack_st_x509 in Swift? - c

I've finally managed to get code working to validate a CMS signature in Swift using OpenSSL's CMS_Verify method. Now I would like to use the STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) method to get the certificates used to sign the message. In Swift, the data type for that call would be UnsafeMutablePointer<stack_st_X509>. I'm able to get a value back for that call, so I know it's succeeding. What I don't know, is how to extract the contents of it?
I was reading the STACK API docs and it appears that access to the contents of an OpenSSL stack value is accomplished using a bunch of macros in the OpenSSL code. These macros are not carried over in Swift, however.
Does anyone know how I can go about accessing the stack_st_x509 data in Swift? I'm not terribly familiar with the OpenSSL APIs so I'm somewhat stuck.

If macros are the only way to access the data you cannot do so from swift. You must write C or Objective-C code that gets the data out that you are interested in.
You can then call these wrapper functions from swift to get your data.

Related

FFI: How to Create Native Handle from Which Native Pointer Can be Derived

I am trying to do some audio I/O using PortAudio accessed from Dart via FFI. I am running a current version of Ubuntu 20.04 on a late 2012 Mac Mini with 16GB of RAM. I am coding Dart using WebStorm and C using Eclipse. I have had similar problems attempting this task running macOS 10.15.7 (Catalina) on the same Mac Mini.
PortAudio has one interface quirk in that it uses a pointer to an input or output stream as an argument to many of its functions; however, when opening an input or output stream, you must pass a handle to the stream (&stream) rather than a pointer.
In addition, if called from inside C code, no special pointer initialization is needed prior to calling OpenStream, just declare the stream pointer (stream) and pass its address to OpenStream (&stream), and PortAudio is happy (that's just the way C works).
Unfortunately, I am really struggling with how to create and initialize the pointer and handle in Dart in a way that doesn't return a badStreamPtr error from OpenStream.
There does not seem to be a graceful way to do this in Dart (although I claim no high expertise in Dart, and my C skills have been mostly unused for 20+ years)
The Handle class seems to truly be a marker class (i.e., if you get
a fully formed handle from C, you can store it in Dart, and then
pass it back to C, but there does not seem to be any way to
instantiate or inspect it in Dart that I could tell. My PortAudio test with Handle
failed).
You can create a Pointer in Dart, then pass its address to the value
of another Pointer. While super-clunky, this seemed to be the best
course, but it consistently fails with a paBadStreamPtr error after
being passed to PortAudio. I did note that none of the pointer/handle addresses were changed after the call to OpenStream. I do not know if this is relevant. I kind of expected that the stream itself might be relocated by PortAudio given the need to pass a handle rather than a pointer, but I do not know under what circumstances that might occur. Note that the stream is an opaque structure accessed via a void pointer. That makes debugging even less fun.
To make sure that I had a basic grip on FFI as well as PortAudio, I wrote a small shared library in C that served as a wrapper for a Dart application to access and manipulate PortAudio. That worked fine as I didn't have to deal with the pointer/handle creation/initialization inside Dart; however, I would really like to access PortAudio directly from Dart rather than the C wrapper.
I used ffigen to generate the C bindings to PortAudio.
Here's the C function API:
PaError Pa_OpenStream (PaStream **stream,
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters,
double sampleRate,
unsigned long framesPerBuffer,
PaStreamFlags streamFlags,
PaStreamCallback *streamCallback,
void *userData)
ffigen has translated this into Dart as:
int Pa_OpenStream(
ffi.Pointer<ffi.Pointer<PaStream>> stream,
ffi.Pointer<PaStreamParameters> inputParameters,
ffi.Pointer<PaStreamParameters> outputParameters,
double sampleRate,
int framesPerBuffer,
int streamFlags,
ffi.Pointer<PaStreamCallback> streamCallback,
ffi.Pointer<ffi.Void> userData,)
inputParameters and outputParamters are structs - no problems.
No problems with the primitives and flags (bit masked integers).
I failed miserably with using callbacks. The Dart documentation for
callbacks is all but non-existent, and even the sample callback
code posted on GitHub doesn't seem to include the corresponding C code, so that
makes a difficult task even harder. As such, I am using the PortAudio
blocking option using polling to capture or deliver audio samples
from/to PortAudio. As such, the callback pointer is NULL.
Because of using the blocking approach, userData is NULL.
So...the only challenge remaining (I hope) is figuring out how to get --PaStream** stream-- to work when the pointer and handle are created on the Dart side.
Any ideas, or do I just need to keep a C wrapper in place for the time being?

Updating legacy C code to use OpenSSL getters for opaque structures

I've got this ancient C code that I didn't write, but I need to re-compile against newer OpenSSL with opaque structures. I've updated most of the direct struct access to use the getter functions. This is my first time working directly with the OpenSSL library in C.
I am struggling to complete the final portion of this work, which is to get the following struct members in ASN.1 format as another function needs ASN1_OBJECT passed to it:
cert->cert_info->signature->algorithm
cert->cert_info->key->algor->algorithm
I used X509_get0_tbs_sigalg(cert) to get the signature algorithm from cert, but I couldn't figure out from the i2d_* function manpage what the best practice for getting this to ASN.1 format is. I tried a couple things and felt I was just digging myself into a further hole by potentially doing it wrong.
And I couldn't find a direct way to get the key algorithm at all, I'm guessing I need to get something intermediate first?
I could potentially ditch the other function that requires an ASN1_OBJECT, although I'd like to leave that part of the code alone. Even if I did get rid of the other function that requires ASN1_OBJECT, I would still need the algorithms in string format.
Any suggestions? Thanks!
X509_get0_tbs_sigalg() returns an X509_ALGOR structure. From that you can get an ASN1_OBJECT from it using X509_ALGOR_get0.
https://www.openssl.org/docs/man1.1.1/man3/X509_ALGOR_get0.html
To get the key algorithm first get the key as an X509_PUBKEY object using X509_get_X509_PUBKEY():
https://www.openssl.org/docs/man1.1.1/man3/X509_get_X509_PUBKEY.html
From there you can use X509_PUBKEY_get0_param to get the key algorithm:
https://www.openssl.org/docs/man1.1.1/man3/X509_PUBKEY_get0_param.html

C Handles - How to work with them?

I have in some documentation for a plugin for Dreamweaver I am making that says the following:
void **connectionData
• The connectionData argument is a
handle to the data that the agent
wants Dreamweaver to pass to it when
calling other API functions.
I have no other information than this from the manual in regard to connectionData. Thinking literally, I figured handle refered to a generic handle,however I am not able to find documentation on working with generic handles in regard to C.
HANDLE h = connectionData;
Does compile in my code. How exactly do I get the "secrets" inside this data structure/can someone explain how generic handles for C work?
Well, usually you are not supposed to get the secrets of handles; they are usually just a pointer to some internal structure inside the lib/API you are using and only the lib will know how to use it.
There is no generic rules or anything about handles, you'll have to use them as indicated by your lib's docs.
The way that this is defined, connectionData is a pointer to a pointer to something. Without knowing what is assigned to connectionData, you can't know anything else. The reason why your other statement worked is that HANDLE is probably a macro that expands to void*
To know the "Secrets," you would need to find out what struct (this is a guess - it could actually be any data type) connectionData points to, then look at the definition of that struct. I don't know how familiar you are with programming in general but a debugger allows you to easily look at the struct's fields while paused at a breakpoint.
However, as other people have said, you probably don't want to muck with the internals of whatever this points to, and only use API calls.
C developers use a "handle" data type when they specifically want to hide the internal data and keep API users from monkeying around with the implementation. A handle is sometimes just a pointer, but can also be an index into an internal lookup table.
In general, you should only use provided API functions with a handle, and learn the proper way to get the handle, understand its life cycle and how to properly dispose of it when you're done.

Access Client Write Key & Server Write Key from OpenSSL C API

I have a need to access the encryption (cipher, write) keys that are generated from the master key that is generated from the OpenSSL C API. I know I can access the master key using the SSL struct as follows:
ssl->session->master_key
Unfortunately looking at the OpenSSL code has not gotten me very far as the API is not very well documented and looking at GDB has been a pain as well. Are they exposed anywhere?
Thanks
I am working on the same thing as well.
Well for the SSlv3 connections, you can access the key block by,
ssl->s3->tmp.key_block
However, I managed to get this at the end of ssl3_setup_key_block method which is defined in s3_enc.c file. I mean I changed the source code and recompiled openssl. So I don't know yet if it changes or becomes lost after returning from that function.
This key block is a string and as defined in http://www.ietf.org/rfc/rfc2246.txt its structure is;
{
clientWriteMACSecret,
serverWriteMACSecret,
clientWriteKey,
serverWriteKey,
clientWriteIV,
serverWriteIV
}
The length of each section varies depending on the used cipher suite.
For SSLv2 connections I suppose you can again access these areas by calling ssl->s2->something as well. s2 is an object of ssl2_state_st structure which is defined in ssl2.h. You can look that up from there.
I don't know how it is for TLSv1 connections. But there is also a d1 variable in the SSL structure.
As a personal note, openssl source code is really a bunch of trash. No good code comments, no good documentation. Wandering inside the source code in order to find the simplest thing is a pain.

need base64 encode/decode in c

I need a function to encode base64 and a function to decode base64 string in c. I found http://base64.sourceforge.net/b64.c but the functions work on files, not strings, and add line breaks. I need one that simply encodes/decodes strings. Where can I find such a sourcecode?
Get the functions from libb64.
If you have openssl available to you (which most *nix distros seem to have out-of-the-box these days), it provides robust, well-tested base64 encoding/decoding out of the box. This site has a decent code sample: Howto base64 decode with C/C++ and OpenSSL
When I needed to use Base64 encoding to build an encrypted email server, I decided to build my own implementation.
Currently, it's placed within a C++ class; but I wrote the encoding functions without using any c++ specific code, so you can copy and paste as you please.
This implementation is not approved by any organizations; but it should help you with learning how the algorithm works, while also giving you access to just base64 encoding. IE: no extra libraries get included.
https://github.com/AlexBestoso/Base64
Use as you please. The functions take chars, maps them to an integer via bit-wise operations, and then produces your result.
Currently, there's no newline or carriage return, which specified in the MIME implementation.
If you decide to use the code and find any bugs, let me know through github.

Resources