Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty Extensions Sequence #1479

Closed
mtgag opened this issue Aug 22, 2023 · 2 comments
Closed

Empty Extensions Sequence #1479

mtgag opened this issue Aug 22, 2023 · 2 comments

Comments

@mtgag
Copy link
Contributor

mtgag commented Aug 22, 2023

It is possible to create an empty sequence of extensions in certificates, CRLs and probably other PKI structures that use extensions.
The ASN.1 specification requires that the sequence is not empty:

Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension

A small programm that creates an empty sequence of extensions is the following:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;

public class CreateEmptyExtenionsSequence {

    public static void main(String[] args) throws IOException {

        Extension[] emptyExtensions = new Extension[0];
        Extensions extensions = new Extensions(emptyExtensions);
        Files.write(Paths.get("emptySeq.der"), extensions.getEncoded(ASN1Encoding.DER));
    }

}

The caller of the constructor should not place empty extensions at all on the first place. However, if this done then the extenions are created as an empty sequence. We propose a more strict cheking in BC to disallow this behaviour, for example by checking if the length of the array is 0 and throwing an appropriate exception.
For example

could be changed to:

public Extensions(Extension[] extensions)
{

    if (extensions == null || extensions.length == 0) {
        throw new IllegalArgumentException("extension array cannot be null or empty");
    }

    for (int i = 0; i != extensions.length; i++)
    {
        Extension ext = extensions[i];

        this.ordering.addElement(ext.getExtnId());
        this.extensions.put(ext.getExtnId(), ext);
    }
}

Thic could also be addittionally captured here

private Extensions(
        ASN1Sequence seq)
{

    if (seq == null || seq.size() == 0) {
        throw new IllegalArgumentException("extension sequence cannot be null or empty");
    }

    Enumeration e = seq.getObjects();

    while (e.hasMoreElements())
    {
        Extension ext = Extension.getInstance(e.nextElement());

        if (extensions.containsKey(ext.getExtnId()))
        {
            throw new IllegalArgumentException("repeated extension found: " + ext.getExtnId());
        }

        extensions.put(ext.getExtnId(), ext);
        ordering.addElement(ext.getExtnId());
    }
}

Also a minor change could be done here:

* an object for the elements in the X.509 V3 extension block.

to describe that the extension object can be used in CRLs and CRL entries, OCSP etc., e.g.

/**
 * an object for the elements in the X.509 extension block of V3 certificates, the crlExtensions and crlEntryExtensions blocks of V2 CRLs and extension blocks in OCSP requests and responses.
 */

or simply:

/**
 * an object for the elements in the X.509 extensions.
 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
 */
@mtgag
Copy link
Contributor Author

mtgag commented Aug 23, 2023

We could also consider such positions for more strict checks:

to change to:

 return c.getExtensions() != null && c.getExtensions().getExtensionOIDs() != null && c.getExtensions().getExtensionOIDs().length > 0

And similar positions like

ff-wl pushed a commit to ff-wl/bc-java that referenced this issue Aug 28, 2023
ff-wl pushed a commit to ff-wl/bc-java that referenced this issue Aug 28, 2023
@dghgit
Copy link
Contributor

dghgit commented Sep 10, 2023

I think this is now covered. Thanks for the report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants