Skip to content

Commit

Permalink
Ed25519 key generation using bouncycastle lib added, modification in …
Browse files Browse the repository at this point in the history
…test case, name column added, active and authority column removed
  • Loading branch information
nitin-vavdiya committed May 23, 2023
1 parent d8d1984 commit b13bf28
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Wallet extends BaseEntity{
public class Wallet extends BaseEntity {

@Id
@JsonIgnore
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", columnDefinition = "serial", nullable = false, unique = true)
private Long id;

@Column(nullable = false)
private String name;

@Column(nullable = false, unique = true)
private String did;

Expand All @@ -51,13 +54,7 @@ public class Wallet extends BaseEntity{

@Column(nullable = false)
private String algorithm;

@Column(nullable = false)
private Boolean active;

@Column(nullable = false)
private Boolean authority;


@Column(nullable = false)
private String didDocument;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* *******************************************************************************
* Copyright (c) 2021,2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
* ******************************************************************************
*/

package org.eclipse.tractusx.managedidentitywallets.exception;

/**
* The type Wallet creation problem.
*/
public class WalletCreationProblem extends RuntimeException {
/**
* Instantiates a new Wallet creation problem.
*/
public WalletCreationProblem() {
}

/**
* Instantiates a new Wallet creation problem.
*
* @param message the message
*/
public WalletCreationProblem(String message) {
super(message);
}

/**
* Instantiates a new Wallet creation problem.
*
* @param message the message
* @param cause the cause
*/
public WalletCreationProblem(String message, Throwable cause) {
super(message, cause);
}

/**
* Instantiates a new Wallet creation problem.
*
* @param cause the cause
*/
public WalletCreationProblem(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings;
import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet;
import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey;
Expand All @@ -40,14 +47,12 @@
import org.eclipse.tractusx.ssi.lib.model.did.Did;
import org.eclipse.tractusx.ssi.lib.model.did.DidDocument;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.FileSystemUtils;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.StringWriter;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.List;
import java.util.UUID;

/**
* The type Wallet service.
Expand Down Expand Up @@ -99,7 +104,7 @@ public Wallet createWallet(CreateWalletRequest request) {
Ed25519KeySet keyPair = createKeyPair();

//create did json
Did did = DidWebFactory.fromHostname(miwSettings.host()+":"+request.getBpn());
Did did = DidWebFactory.fromHostname(URLDecoder.decode(miwSettings.host() + ":" + request.getBpn(), Charset.defaultCharset()));
DidDocument didDocument = new DidDocumentBuilder()
.withDid(did)
.withEd25519PublicKey(keyPair.getPublicKey())
Expand All @@ -110,9 +115,8 @@ public Wallet createWallet(CreateWalletRequest request) {
Wallet wallet = walletRepository.save(Wallet.builder()
.didDocument("did document") //TODO remove once we have solution in lib didDocument.toString or didDocument.toJson
.bpn(request.getBpn())
.name(request.getName())
.did(did.toString())
.active(true)
.authority(true)
.algorithm("ED25519")
.build());

Expand All @@ -121,8 +125,8 @@ public Wallet createWallet(CreateWalletRequest request) {
.walletId(wallet.getId())
.referenceKey("dummy ref key") //TODO removed once vault setup is ready
.vaultAccessToken("dummy vault access token") ////TODO removed once vault setup is ready
.publicKey(encryptionUtils.encrypt(new String(keyPair.getPrivateKey())))
.privateKey(encryptionUtils.encrypt(new String(keyPair.getPublicKey())))
.privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey())))
.publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey())))
.build());
log.debug("Wallet created for bpn ->{}", request.getBpn());
return wallet;
Expand All @@ -137,41 +141,37 @@ private void validateCreateWallet(CreateWalletRequest request){
}

@SneakyThrows
private Ed25519KeySet createKeyPair(){

String keyLocation = "/tmp/"+ UUID.randomUUID();
Files.createDirectories(Paths.get(keyLocation));

File privateKey = new File(keyLocation+"/private.pem");
File publicKey = new File(keyLocation+"/public.pem");
try{
//private key
if(!privateKey.exists()){
privateKey.createNewFile();
}
Process privateKeyProcess = Runtime.getRuntime().exec("openssl genpkey -algorithm ed25519");
try( BufferedReader privateKeyReader = new BufferedReader(new InputStreamReader(privateKeyProcess.getInputStream()));
BufferedWriter privateKeyWriter = new BufferedWriter(new FileWriter(privateKey))){
FileCopyUtils.copy(privateKeyReader, privateKeyWriter);
}

//public key
if(!publicKey.exists()){
publicKey.createNewFile();
}
Process publicKeyProcess = Runtime.getRuntime().exec("openssl pkey -in "+privateKey.getAbsolutePath()+" -pubout");
try(BufferedReader publicKeyReader = new BufferedReader(new InputStreamReader(publicKeyProcess.getInputStream()));
BufferedWriter publicKeyWriter = new BufferedWriter(new FileWriter(publicKey))){
FileCopyUtils.copy(publicKeyReader, publicKeyWriter);
}
return new Ed25519KeySet(readPEMFile(privateKey.getAbsolutePath()), readPEMFile(publicKey.getAbsolutePath()));
}finally {
FileSystemUtils.deleteRecursively(Paths.get(keyLocation));
}
private Ed25519KeySet createKeyPair() {
SecureRandom secureRandom = new SecureRandom();

Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator();
keyPairGenerator.init(new Ed25519KeyGenerationParameters(secureRandom));

AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair();
Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters) keyPair.getPrivate();
Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters) keyPair.getPublic();

byte[] privateKeyBytes = privateKey.getEncoded();
byte[] publicKeyBytes = publicKey.getEncoded();
return new Ed25519KeySet(privateKeyBytes, publicKeyBytes);
}


@SneakyThrows
private String getPrivateKeyString(byte[] privateKeyBytes) {
StringWriter stringWriter = new StringWriter();
JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter);
pemWriter.writeObject(PrivateKeyInfoFactory.createPrivateKeyInfo(new Ed25519PrivateKeyParameters(privateKeyBytes, 0)));
pemWriter.close();
return stringWriter.toString();
}

private byte[] readPEMFile(String path) throws IOException {
PemReader pemReader = new PemReader(new FileReader(path));
return pemReader.readPemObject().getContent();
@SneakyThrows
private String getPublicKeyString(byte[] publicKeyBytes) {
StringWriter stringWriter = new StringWriter();
JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter);
pemWriter.writeObject(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new Ed25519PublicKeyParameters(publicKeyBytes, 0)));
pemWriter.close();
return stringWriter.toString();
}
}
11 changes: 4 additions & 7 deletions src/main/resources/db/changelog/changes/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
--changeset nitin:1
CREATE TABLE public.wallet (
id bigserial NOT NULL,
name varchar(255) NOT NULL,
did varchar(255) NOT NULL,
bpn varchar(255) NOT NULL,
algorithm varchar(255) NOT NULL DEFAULT 'ED25519'::character varying,
active bool NOT NULL,
authority bool NOT NULL,
did_document text NOT NULL,
created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified_at timestamp(6) NULL,
Expand All @@ -24,6 +23,8 @@ CREATE TABLE public.wallet_key (
wallet_id bigserial NOT NULL,
vault_access_token varchar(1000) NOT NULL,
reference_key varchar(255) NOT NULL,
private_key text NOT NULL,
public_key text NOT NULL,
created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified_at timestamp(6) NULL,
modified_from varchar(255) NULL,
Expand All @@ -46,8 +47,4 @@ CREATE TABLE public.credential (
CONSTRAINT credential_fk FOREIGN KEY (modified_from) REFERENCES public.wallet(bpn),
CONSTRAINT holder_wallet_fk FOREIGN KEY (holder) REFERENCES public.wallet(id),
CONSTRAINT issuer_wallet_fk FOREIGN KEY (issuer) REFERENCES public.wallet(id)
);

--changeset nitin:2
ALTER TABLE public.wallet_key ADD private_key text NOT NULL;
ALTER TABLE public.wallet_key ADD public_key text NOT NULL;
);
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class WalletTest {


@Test
void encryptionTest(){
void encryptionTest() {
String originalMassage = "Dummy test message";
String encrypt = encryptionUtils.encrypt(originalMassage);
String decrypt = encryptionUtils.decrypt(encrypt);
Expand All @@ -80,17 +80,25 @@ void encryptionTest(){

@Test
@Order(1)
void createWalletTest201(){
void createWalletTest201() {
CreateWalletRequest request = CreateWalletRequest.builder().bpn(bpn).name(name).build();

ResponseEntity<Wallet> response = restTemplate.exchange(RestURI.WALLETS, HttpMethod.POST, new HttpEntity<>(request), Wallet.class);
Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value());
Assertions.assertNotNull(response.getBody());

Wallet wallet = walletRepository.getByBpn(bpn);
Assertions.assertEquals(response.getBody().getBpn(), bpn);
Assertions.assertEquals(response.getBody().getName(), name);

Wallet wallet = walletRepository.getByBpn(bpn);
Assertions.assertEquals(wallet.getBpn(), bpn);
Assertions.assertEquals(wallet.getName(), name);
Assertions.assertNotNull(wallet);
WalletKey walletKey = walletKeyRepository.getByWalletId(wallet.getId());
Assertions.assertNotNull(walletKey);

Assertions.assertEquals(wallet.getBpn(), bpn);

}

@Test
Expand Down

0 comments on commit b13bf28

Please sign in to comment.