4

I have some string, that is separated with comma. I have to add all extension that match any of GeneralName for Subject Alternative Names extension. Can somebody finish for loop for me?

    @Override
public boolean saveKeypair(String arg0) {

    KeyPair keyPair = generateKeyPair(Integer.parseInt(access.getPublicKeyParameter()));

    PrivateKey privateKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    X500Name name = new X500Name(access.getSubject());
    BigInteger serial = new BigInteger(access.getSerialNumber());
    Date notBefore = access.getNotBefore();
    Date notAfter = access.getNotAfter();
    X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(name, serial, notBefore, notAfter, name,
            publicKey);

    // BEGIN extensions
    // certificate policies
    boolean isCritPol = access.isCritical(3);
    PolicyInformation[] policies = new PolicyInformation[1];
    policies[0] = new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.2.1.11.5"),
            new DERSequence(new PolicyQualifierInfo(access.getCpsUri())));
    try {
        certBuilder.addExtension(Extension.certificatePolicies, isCritPol, new CertificatePolicies(policies));
    } catch (CertIOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    // END CP

    // subject alternative name
    List<GeneralName> altNames = new ArrayList<GeneralName>();
    String [] altSubNames = access.getAlternativeName(5);

    for(String altName : altSubNames){
        // I NEED THIS LOOP, AND I DON'T KNOW HOW TO DO IT
    }

    // END SAN

    // END extensions


    try {
        // Content Signer
        Security.addProvider(new BouncyCastleProvider());
        ContentSigner sigGen = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(providerName)
                .build(privateKey);

        // Certificate
        X509Certificate certificate = new JcaX509CertificateConverter().setProvider(providerName)
                .getCertificate(certBuilder.build(sigGen));

     certificate.verify(publicKey);

        X509Certificate[] chain = new X509Certificate[1];       
        chain[0] = certificate;
        keyStore.setKeyEntry(arg0, privateKey, password.toCharArray(), chain);

    } catch (OperatorCreationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CertificateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SignatureException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (KeyStoreException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return true;
}

// BEGIN of functions for saveKeypair

public KeyPair generateKeyPair(int keySize) {
    KeyPair keyPair = null;

    try {
        KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(algorithm);
        keyGenerator.initialize(keySize);
        keyPair = keyGenerator.generateKeyPair();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    return keyPair;
}



// END of functions for saveKeypair

The rest of the function is working.

I am using BouncyCastle in Java. altSubName is an array, of some Strings. And those Strings should be somehow checked which of SubjectAlternativeName they are, and the Extension containing all that general names should be added.

Isidora Bojovic
  • 101
  • 2
  • 5
  • 2
    *Can somebody finish for loop for me??* We are not a remote programming facility for you, finish it yourself. Stop using StackOverflow as a shortcut for your laziness. – t0mm13b Jun 07 '17 at 21:25
  • I am not lazy, i have tried some ways that are not correct. I could just posted my incorrect function, and than this would be ok question? I really need help with this one. Because everything I found on Internet is about adding only one Alternative Name. – Isidora Bojovic Jun 07 '17 at 23:03
  • I have one idea, and that is to use regex and check what is the type of Alternative Name, I am interested if there is some better solution? – Isidora Bojovic Jun 07 '17 at 23:09
  • A GeneralName can be of lots of different types (dnsName, ipAddress, rfc822name and so on), do you know what exactly your strings should be? You said "Strings should be somehow checked which of SubjectAlternativeName they are" - do you have some examples of the strings and how it's decided their types? –  Jun 08 '17 at 01:03
  • And what version of BouncyCastle are you using? –  Jun 08 '17 at 01:34
  • It can be any string. I must recognize if string is dnsName, ipAddress, rfc822name and so on, and to add it. – Isidora Bojovic Jun 08 '17 at 11:24

1 Answers1

4

According to RFC 5280, some fields of the Subject Alternative Name extension have a defined format:

And so on (take a look at the RFC 5280 link, it's very detailed).

So, to know what's the field corresponding to each String, you must check if they have the format defined in each of the fields.

For rfc822Name I've found this monster regex:

String rfc822Regex = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
String s = "test_ad.fade@mail.com";
if (s.matches(rfc822Regex)) {
    // is valid email
}

For the other fields, you can search regexes for each specific format. I think the only problem is the otherName field, because it can have any format (it must be specified for each Certificate Authority):

OtherName ::= SEQUENCE {
    type-id    OBJECT IDENTIFIER,
    value      [0] EXPLICIT ANY DEFINED BY type-id }

Anyway, a generic code will be like this (assuming you already searched how to validate each of the specific formats):

// check the format and add with the correct field type
if (isValidEmail(altName)) {
    altNames.add(new GeneralName(GeneralName.rfc822Name, "user@mail.com"));
} else if (isValidDnsName(altName)) {
    altNames.add(new GeneralName(GeneralName.dNSName, "test.com"));
} else if (isValidIpAddress(altName)) {
    altNames.add(new GeneralName(GeneralName.iPAddress, "127.0.0.1"));
}
// ... and so on, for all GeneralName types

Then you add the extension to certBuilder:

GeneralNames subjectAltNames = GeneralNames.getInstance(new DERSequence((GeneralName[]) altNames.toArray(new GeneralName[] {})));
certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
Community
  • 1
  • 1
  • Thank you very much! do you know some more regular expression for some other of GeneralNames? – Isidora Bojovic Jun 08 '17 at 15:42
  • Unfortunately I don't know, but it shouldn't be hard to find (they're all very known standards, maybe even BouncyCastle has it, but I'm not sure) –  Jun 08 '17 at 15:44