| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.plc4x.java.opcua.context; |
| |
| import org.apache.commons.lang3.RandomUtils; |
| import org.bouncycastle.asn1.DERSequence; |
| import org.bouncycastle.asn1.x500.X500NameBuilder; |
| import org.bouncycastle.asn1.x500.style.BCStyle; |
| import org.bouncycastle.asn1.x509.*; |
| import org.bouncycastle.cert.X509CertificateHolder; |
| import org.bouncycastle.cert.X509v3CertificateBuilder; |
| import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; |
| import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; |
| import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| import org.bouncycastle.operator.ContentSigner; |
| import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.math.BigInteger; |
| import java.net.InetAddress; |
| import java.security.KeyPair; |
| import java.security.KeyPairGenerator; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.SecureRandom; |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.Locale; |
| |
| public class CertificateGenerator<PKCS10CertificateRequest> { |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(CertificateGenerator.class); |
| private static final String APPURI = "urn:eclipse:milo:plc4x:server"; |
| |
| public static CertificateKeyPair generateCertificate() { |
| KeyPairGenerator kpg = null; |
| try { |
| kpg = KeyPairGenerator.getInstance("RSA"); |
| } catch (NoSuchAlgorithmException e) { |
| LOGGER.error("Security Algorithim is unsupported for certificate"); |
| } |
| kpg.initialize(2048); |
| KeyPair caKeys = kpg.generateKeyPair(); |
| KeyPair userKeys = kpg.generateKeyPair(); |
| |
| X500NameBuilder nameBuilder = new X500NameBuilder(); |
| |
| nameBuilder.addRDN(BCStyle.CN, "Apache PLC4X Driver Client"); |
| nameBuilder.addRDN(BCStyle.O, "Apache Software Foundation"); |
| nameBuilder.addRDN(BCStyle.OU, "dev"); |
| nameBuilder.addRDN(BCStyle.L, ""); |
| nameBuilder.addRDN(BCStyle.ST, "DE"); |
| nameBuilder.addRDN(BCStyle.C, "US"); |
| |
| BigInteger serial = new BigInteger(RandomUtils.nextBytes(40)); |
| |
| final Calendar calender = Calendar.getInstance(); |
| calender.add(Calendar.DATE, -1); |
| Date startDate = calender.getTime(); |
| calender.add(Calendar.DATE, 365*25); |
| Date expiryDate = calender.getTime(); |
| |
| KeyPairGenerator generator = null; |
| try { |
| generator = KeyPairGenerator.getInstance("RSA"); |
| generator.initialize(2048, new SecureRandom()); |
| KeyPair keyPair = generator.generateKeyPair(); |
| |
| SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance( |
| keyPair.getPublic().getEncoded() |
| ); |
| |
| X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder( |
| nameBuilder.build(), |
| serial, |
| startDate, |
| expiryDate, |
| Locale.ENGLISH, |
| nameBuilder.build(), |
| subjectPublicKeyInfo |
| ); |
| |
| GeneralName[] gnArray = new GeneralName[] {new GeneralName(GeneralName.dNSName, InetAddress.getLocalHost().getHostName()), new GeneralName(GeneralName.uniformResourceIdentifier, APPURI)}; |
| |
| certificateBuilder.addExtension(Extension.authorityKeyIdentifier, false, new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(keyPair.getPublic())); |
| certificateBuilder.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(new KeyPurposeId[]{KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth})); |
| certificateBuilder.addExtension(Extension.keyUsage,false, new KeyUsage(KeyUsage.dataEncipherment | KeyUsage.digitalSignature | KeyUsage.keyAgreement | KeyUsage.keyCertSign | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation)); |
| certificateBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true)); |
| |
| GeneralNames subjectAltNames = GeneralNames.getInstance(new DERSequence(gnArray)); |
| certificateBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltNames); |
| |
| ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(keyPair.getPrivate()); |
| |
| X509CertificateHolder certificateHolder = certificateBuilder.build(sigGen); |
| |
| JcaX509CertificateConverter certificateConvertor = new JcaX509CertificateConverter(); |
| certificateConvertor.setProvider(new BouncyCastleProvider()); |
| |
| CertificateKeyPair ckp = new CertificateKeyPair(keyPair, certificateConvertor.getCertificate(certificateHolder)); |
| |
| return ckp; |
| |
| } catch (Exception e) { |
| LOGGER.error("Security Algorithm is unsupported for certificate"); |
| return null; |
| } |
| } |
| } |