Skip to content

Fix issue #79: Make DirectoryStringChoiceType configurable #54

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public class X509CertificateConfig implements Serializable {
@XmlElementWrapper
private List<Pair<X500AttributeType, String>> subject;

@XmlElement(name = "attributeField")
private DirectoryStringChoiceType defaultDirectoryStringType =
DirectoryStringChoiceType.UTF8_STRING;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* X.509-Attacker - A Library for Arbitrary X.509 Certificates
*
* Copyright 2014-2023 Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH
*
* Licensed under Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0.txt
*/
package de.rub.nds.x509attacker.config;

import static org.junit.jupiter.api.Assertions.*;

import de.rub.nds.x509attacker.constants.DirectoryStringChoiceType;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import org.junit.jupiter.api.Test;

class X509CertificateConfigTest {

@Test
void testDefaultDirectoryStringTypeConfigurable() {
X509CertificateConfig config = new X509CertificateConfig();

// Test default value
assertEquals(DirectoryStringChoiceType.UTF8_STRING, config.getDefaultDirectoryStringType());

// Test setting different values
config.setDefaultDirectoryStringType(DirectoryStringChoiceType.PRINTABLE_STRING);
assertEquals(
DirectoryStringChoiceType.PRINTABLE_STRING, config.getDefaultDirectoryStringType());

config.setDefaultDirectoryStringType(DirectoryStringChoiceType.BMP_STRING);
assertEquals(DirectoryStringChoiceType.BMP_STRING, config.getDefaultDirectoryStringType());

config.setDefaultDirectoryStringType(DirectoryStringChoiceType.TELETEX_STRING);
assertEquals(
DirectoryStringChoiceType.TELETEX_STRING, config.getDefaultDirectoryStringType());

config.setDefaultDirectoryStringType(DirectoryStringChoiceType.UNIVERSAL_STRING);
assertEquals(
DirectoryStringChoiceType.UNIVERSAL_STRING, config.getDefaultDirectoryStringType());
}

@Test
void testDefaultDirectoryStringTypeXmlSerialization() throws Exception {
// Create config with non-default value
X509CertificateConfig originalConfig = new X509CertificateConfig();
originalConfig.setDefaultDirectoryStringType(DirectoryStringChoiceType.PRINTABLE_STRING);

// Serialize to XML
JAXBContext context = JAXBContext.newInstance(X509CertificateConfig.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

StringWriter writer = new StringWriter();
marshaller.marshal(originalConfig, writer);
String xml = writer.toString();

// Verify XML contains the setting
assertTrue(xml.contains("defaultDirectoryStringType"));
assertTrue(xml.contains("PRINTABLE_STRING"));

// Deserialize from XML
Unmarshaller unmarshaller = context.createUnmarshaller();
X509CertificateConfig deserializedConfig =
(X509CertificateConfig) unmarshaller.unmarshal(new StringReader(xml));

// Verify the value was preserved
assertEquals(
DirectoryStringChoiceType.PRINTABLE_STRING,
deserializedConfig.getDefaultDirectoryStringType());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* X.509-Attacker - A Library for Arbitrary X.509 Certificates
*
* Copyright 2014-2023 Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH
*
* Licensed under Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0.txt
*/
package de.rub.nds.x509attacker.x509.model;

import static org.junit.jupiter.api.Assertions.*;

import de.rub.nds.asn1.model.Asn1PrintableString;
import de.rub.nds.asn1.model.Asn1Utf8String;
import de.rub.nds.protocol.xml.Pair;
import de.rub.nds.x509attacker.config.X509CertificateConfig;
import de.rub.nds.x509attacker.constants.DirectoryStringChoiceType;
import de.rub.nds.x509attacker.constants.NameType;
import de.rub.nds.x509attacker.constants.X500AttributeType;
import de.rub.nds.x509attacker.context.X509Context;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;

class AttributeTypeAndValueTest {

@Test
void testDirectoryStringChoiceTypeConfigurable() {
// Test with UTF8_STRING (default)
AttributeTypeAndValue attrUtf8 =
new AttributeTypeAndValue(
"test",
X500AttributeType.COMMON_NAME,
"Test Value",
DirectoryStringChoiceType.UTF8_STRING);
assertTrue(attrUtf8.getValue() instanceof Asn1Utf8String);

// Test with PRINTABLE_STRING
AttributeTypeAndValue attrPrintable =
new AttributeTypeAndValue(
"test",
X500AttributeType.COMMON_NAME,
"Test Value",
DirectoryStringChoiceType.PRINTABLE_STRING);
assertTrue(attrPrintable.getValue() instanceof Asn1PrintableString);
}

@Test
void testConfigurableDirectoryStringTypeInCertificate() {
// Create config with PRINTABLE_STRING
X509CertificateConfig config = new X509CertificateConfig();
config.setDefaultDirectoryStringType(DirectoryStringChoiceType.PRINTABLE_STRING);

// Create subject with the config
List<Pair<X500AttributeType, String>> subjectAttributes = new ArrayList<>();
subjectAttributes.add(new Pair<>(X500AttributeType.COMMON_NAME, "test.example.com"));
subjectAttributes.add(new Pair<>(X500AttributeType.ORGANISATION_NAME, "Test Org"));
config.setSubject(subjectAttributes);

// Create Name with the configured directory string type
Name name =
new Name(
"subject",
NameType.SUBJECT,
subjectAttributes,
config.getDefaultDirectoryStringType(),
new ArrayList<>());

// Verify that all AttributeTypeAndValue objects use PRINTABLE_STRING
for (RelativeDistinguishedName rdn : name.getRelativeDistinguishedNames()) {
for (AttributeTypeAndValue atav : rdn.getAttributeTypeAndValueList()) {
if (atav.getValue() instanceof DirectoryString) {
DirectoryString ds = (DirectoryString) atav.getValue();
// The DirectoryString will be properly set during preparation
} else {
// Direct string types
assertTrue(
atav.getValue() instanceof Asn1PrintableString,
"Expected PrintableString but got: "
+ atav.getValue().getClass().getSimpleName());
}
}
}
}

@Test
void testDifferentEncodingTypes() {
DirectoryStringChoiceType[] types = {
DirectoryStringChoiceType.UTF8_STRING,
DirectoryStringChoiceType.PRINTABLE_STRING,
DirectoryStringChoiceType.BMP_STRING,
DirectoryStringChoiceType.TELETEX_STRING,
DirectoryStringChoiceType.UNIVERSAL_STRING
};

for (DirectoryStringChoiceType type : types) {
X509CertificateConfig config = new X509CertificateConfig();
config.setDefaultDirectoryStringType(type);

// Create certificate with the config
X509Context context = new X509Context(config);
X509Certificate cert = new X509Certificate("cert");
TbsCertificate tbs = new TbsCertificate("tbs", config);

// The directory string type from config should be used
assertEquals(type, config.getDefaultDirectoryStringType());
}
}
}