1
votes

first of all: Sorry for my bad english. I hope you can understand me.

I using OpenSSL 1.0.2 and I have some problems with it. I have a STACK_OF(X509) object with three certificates and I want to convert this stack to an ASN1 object (like OCTET STRING or ANY). Is this possible? I use an external asn.1 library and not OpenSSL-ASN1. So I need the data as unsigned char (raw binary or DER encoded).

I can convert a single certificate via i2d_X509() into DER format. This is good, but I want the complete stack. This is my goal:

myAsn1Data ::= sequence {
    ...  -- (some ASN.1 data)
    ...  -- (some ASN.1 data)
    ANY  -- contain the DER encoded STACK_OF(X509)....somehow
}

But possibly is this the right way (ASN.1 syntax):

stackOfX509 ::= SEQUENCE_Of {
    TBSCertificate  
}

or like this:

stackOfX509 ::= SET_OF {
    ANY  -- contain a DER encoded X509 certificate
}

I hope someone can help me.

1

1 Answers

0
votes

People normally do one of two things for this.

1) "Cheat"! If the DER encoded representation of the certificate is available but the original schema for it is not, simply have an OCTET STRING to store the bytes.

myAsn1Data ::= SEQUENCE {
    ..., -- (some ASN.1 Data)
    ..., -- (some ASN.1 Data)
    cert [2] OCTET STRING -- (the DER bytes would go in this field)
}

and the flow of your application code would be something like

myAsn1Data data = new(myAsn1Data);
data.cert = readbytesfromfile(certificatefile);
data.something = 10;
data.else = 20;
asn1encode(data, outputfile)

2) Acquire the original schema for an X509 certificate. It ought to be in here somewhere, looks like section 7.2. With this the source your ASN.1 compiler will create for you should be able to decode the certificate, allowing you to place it inside an instance of your myAsn1Data.

IMPORTS Certificate FROM <ITU's X509 Schema file>

CertificateStack ::= SEQUENCE of Certificate

myAsn1Data ::= SEQUENCE {
    ..., -- (some ASN.1 Data)
    ..., -- (some ASN.1 Data)
    cert [2] CertificateStack
}

and the sequences in your application code would look something like this:

Certificate cert1 = asn1decode(certificatefile);
Certificate cert2 = asn1decode(anothercertificatefile);
Certificate cert3 = asn1decode(yetanothercertificatefile);
CertificateStack stack;
stack.push_back(cert1);
stack.push_back(cert2);
stack.push_back(cert3);
myAsn1Data data = new(myAsn1Data);
data.cert = stack;
data.something = 10;
data.else = 20;
asn1encode(data, outputfile)

This way is better because it completely defines what the 'cert' field actually is. The first way isn't quite so good if you are exchanging data with someone else because they need to be told what the cert field actually is.