Skip to content
This repository has been archived by the owner on Oct 6, 2023. It is now read-only.

Commit

Permalink
Merge pull request #133 from SoftwareAG/feature/#2_connect-to-nexus-api
Browse files Browse the repository at this point in the history
Feature/#2 connect to nexus api
  • Loading branch information
iviliev committed Jul 5, 2022
2 parents 7cafae6 + 4466889 commit 7b10891
Show file tree
Hide file tree
Showing 9 changed files with 434 additions and 10 deletions.
37 changes: 34 additions & 3 deletions pkiintegration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>com.cumulocity</groupId>
<artifactId>pki-integration</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>pkiintegration</name>
<name>pki-integration</name>
<description>Microservice for pki-integration</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand All @@ -17,7 +17,7 @@
<maven.compiler.target>11</maven.compiler.target>

<main.class>com.cumulocity.pkiintegration.PkiintegrationApplication</main.class>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<c8y.version>1009.0.28</c8y.version>
Expand Down Expand Up @@ -95,6 +95,23 @@
<artifactId>device-capability-model</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.58</version>
</dependency>
</dependencies>

<build>
Expand All @@ -105,7 +122,7 @@
<filtering>true</filtering>
<includes>
<include>**/application.properties</include>
<include>**/banner.txt</include>
<include>**/certificate/so38.2.p12</include>
</includes>
</resource>
</resources>
Expand All @@ -128,6 +145,20 @@
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<!-- The filter suffix is pem、pfx Certificate file for -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pem</nonFilteredFileExtension>
<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>

<plugin>
<groupId>com.nsn.cumulocity.clients-java</groupId>
<artifactId>microservice-package-maven-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.cumulocity.pkiintegration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
import com.cumulocity.microservice.autoconfigure.MicroserviceApplication;
import com.cumulocity.microservice.context.annotation.EnableContextSupport;

@EnableContextSupport
@MicroserviceApplication
public class PkiintegrationApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.cumulocity.pkiintegration.configuration;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyManagementException;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Enumeration;

import javax.net.ssl.SSLContext;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class RestTemplateConfig {

// TODO: Move to tenant options
private static final String AUTHENTICATION_CERTIFICATE_PATH = "classpath:certificate/so38.2.p12";
// TODO: Move to tenant options
private static final String CERTIFICATE_PASSWORD = "FU63C84I";

@Autowired
private ResourceLoader resourceLoader;

@Bean
public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException {
log.info("Initializing RestTemplate to connect with Certificate-Authority API");
KeyStore clientStore = KeyStore.getInstance("PKCS12");
InputStream inputStream = resourceLoader.getResource(AUTHENTICATION_CERTIFICATE_PATH).getInputStream();
clientStore.load(inputStream, CERTIFICATE_PASSWORD.toCharArray());
printCertificates(CERTIFICATE_PASSWORD, clientStore);
SSLContext sslContext = SSLContextBuilder.create()
.loadKeyMaterial(clientStore, CERTIFICATE_PASSWORD.toCharArray())
.loadTrustMaterial(clientStore, new TrustSelfSignedStrategy() {
@Override
public boolean isTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException {
return true;
}
}).build();

SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}

// This method is for debugging only, to print the keys contained in a
// certificate.
// TODO: can be deleted later.
private void printCertificates(String certificatePassword, KeyStore clientStore)
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
Enumeration<?> aliasEnum = clientStore.aliases();

Key key = null;
Certificate cert = null;

while (aliasEnum.hasMoreElements()) {
String keyName = (String) aliasEnum.nextElement();
key = clientStore.getKey(keyName, certificatePassword.toCharArray());
cert = clientStore.getCertificate(keyName);
}

KeyPair kp = new KeyPair(cert.getPublicKey(), (PrivateKey) key);
System.out.println(kp.getPrivate());
System.out.println(kp.getPublic());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.cumulocity.pkiintegration.model;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
public class Registration {

@JsonProperty("regid")
private String regId;
@JsonProperty("fqdn")
private String fqdn;
@JsonProperty("officer")
private String officer;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.cumulocity.pkiintegration.rest;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cumulocity.pkiintegration.service.CertificateManagementService;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/certificates")
public class CertificateController {

private final CertificateManagementService certificateManagementService;

@GetMapping("/cacerts")
public ResponseEntity<?> getCacerts() throws Exception {
return ResponseEntity.status(HttpStatus.OK).body(certificateManagementService.getCacerts());
}

@PostMapping("/generateCertificate/{deviceId}")
public ResponseEntity<?> generateCertificate(@PathVariable final String deviceId) throws Exception {
return ResponseEntity.status(HttpStatus.OK).body(certificateManagementService.simpleEnrollRequest(deviceId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.cumulocity.pkiintegration.service;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;

import javax.security.auth.x500.X500Principal;

import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.io.pem.PemObject;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
@RequiredArgsConstructor
public class CSRService {

public Optional<String> GenerateCSR(String deviceExternalId, String tenantId) {
try {
KeyPairGenerator keyGen;
keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keypair = keyGen.genKeyPair();

// X500Principal subject = new X500Principal("CN=local.zedwood.com, O=zedwood,
// OU=org, L=Orem, ST=Utah, C=US");
X500Principal subject = new X500Principal("CN=" + deviceExternalId + tenantId);

PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(subject,
keypair.getPublic());
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
ContentSigner signer;
signer = csBuilder.build(keypair.getPrivate());
PKCS10CertificationRequest csr = p10Builder.build(signer);
PemObject pemObject = new PemObject("CERTIFICATE REQUEST", csr.getEncoded());
Writer csrStringWriter = new StringWriter();
JcaPEMWriter pemWriter = new JcaPEMWriter(csrStringWriter);
pemWriter.writeObject(pemObject);
pemWriter.close();
csrStringWriter.close();
return Optional.of(csrStringWriter.toString());
} catch (NoSuchAlgorithmException | OperatorCreationException | IOException e) {
log.error("An error while creating PKCS10 certificate signing request for device {} on tenant {}",
deviceExternalId, tenantId);
log.error(e.getMessage(), e);
return Optional.empty();
}
}
}
Loading

0 comments on commit 7b10891

Please sign in to comment.