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

Feature/#2 connect to nexus api #133

Merged
merged 14 commits into from
Jul 5, 2022
Merged
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
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