Removing AAF references from Cert-Service in OOM repo.
[oom/platform/cert-service.git] / certService / src / main / java / org / onap / oom / certservice / cmpv2client / impl / CmpUtil.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.oom.certservice.cmpv2client.impl;
22
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.security.SecureRandom;
26 import java.util.Date;
27 import java.util.Objects;
28
29 import org.bouncycastle.asn1.ASN1Encodable;
30 import org.bouncycastle.asn1.ASN1EncodableVector;
31 import org.bouncycastle.asn1.ASN1GeneralizedTime;
32 import org.bouncycastle.asn1.DEROctetString;
33 import org.bouncycastle.asn1.DEROutputStream;
34 import org.bouncycastle.asn1.DERSequence;
35 import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers;
36 import org.bouncycastle.asn1.cmp.InfoTypeAndValue;
37 import org.bouncycastle.asn1.cmp.PKIBody;
38 import org.bouncycastle.asn1.cmp.PKIHeader;
39 import org.bouncycastle.asn1.cmp.PKIHeaderBuilder;
40 import org.bouncycastle.asn1.x500.X500Name;
41 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
42 import org.bouncycastle.asn1.x509.GeneralName;
43 import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public final class CmpUtil {
48
49     private static final Logger LOGGER = LoggerFactory.getLogger(CmpUtil.class);
50     private static final SecureRandom SECURE_RANDOM = new SecureRandom();
51     public static final int RANDOM_BYTE_LENGTH = 16;
52     public static final int RANDOM_SEED = 1000;
53
54     private CmpUtil() {
55     }
56
57     /**
58      * Validates specified object reference is not null.
59      *
60      * @param argument T - the type of the reference.
61      * @param message  message - detail message to be used in the event that a NullPointerException is
62      *                 thrown.
63      * @return The Object if not null
64      */
65     public static <T> T notNull(T argument, String message) {
66         return Objects.requireNonNull(argument, message + " must not be null");
67     }
68
69     /**
70      * Validates String object reference is not null and not empty.
71      *
72      * @param stringArg String Object that need to be validated.
73      * @return boolean
74      */
75     public static boolean isNullOrEmpty(String stringArg) {
76         return (stringArg != null && !stringArg.trim().isEmpty());
77     }
78
79     /**
80      * Creates a random number than can be used for sendernonce, transactionId and salts.
81      *
82      * @return bytes containing a random number string representing a nonce
83      */
84     static byte[] createRandomBytes() {
85         LOGGER.info("Generating random array of bytes");
86         byte[] randomBytes = new byte[RANDOM_BYTE_LENGTH];
87         SECURE_RANDOM.nextBytes(randomBytes);
88         return randomBytes;
89     }
90
91     /**
92      * Creates a random integer than can be used to represent a transactionId or determine the number
93      * iterations in a protection algorithm.
94      *
95      * @return bytes containing a random number string representing a nonce
96      */
97     static int createRandomInt(int range) {
98         LOGGER.info("Generating random integer");
99         return SECURE_RANDOM.nextInt(range) + RANDOM_SEED;
100     }
101
102     /**
103      * Generates protected bytes of a combined PKIHeader and PKIBody.
104      *
105      * @param header Header of PKIMessage containing common parameters
106      * @param body   Body of PKIMessage containing specific information for message
107      * @return bytes representing the PKIHeader and PKIBody thats to be protected
108      */
109     static byte[] generateProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException {
110         LOGGER.info("Generating array of bytes representing PkiHeader and PkiBody");
111         byte[] res;
112         ASN1EncodableVector vector = new ASN1EncodableVector();
113         vector.add(header);
114         vector.add(body);
115         ASN1Encodable protectedPart = new DERSequence(vector);
116         try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
117             DEROutputStream out = new DEROutputStream(baos);
118             out.writeObject(protectedPart);
119             res = baos.toByteArray();
120         } catch (IOException ioe) {
121             CmpClientException cmpClientException =
122                     new CmpClientException("IOException occurred while creating protectedBytes", ioe);
123             LOGGER.error("IOException occurred while creating protectedBytes");
124             throw cmpClientException;
125         }
126         return res;
127     }
128
129     /**
130      * Generates a PKIHeader Builder object.
131      *
132      * @param subjectDn     distinguished name of Subject
133      * @param issuerDn      distinguished name of external CA
134      * @param protectionAlg protection Algorithm used to protect PKIMessage
135      * @return PKIHeaderBuilder
136      */
137     static PKIHeader generatePkiHeader(
138             X500Name subjectDn, X500Name issuerDn, AlgorithmIdentifier protectionAlg, String senderKid) {
139         LOGGER.info("Generating a Pki Header Builder");
140         PKIHeaderBuilder pkiHeaderBuilder =
141                 new PKIHeaderBuilder(
142                         PKIHeader.CMP_2000, new GeneralName(subjectDn), new GeneralName(issuerDn));
143
144         pkiHeaderBuilder.setMessageTime(new ASN1GeneralizedTime(new Date()));
145         pkiHeaderBuilder.setSenderNonce(new DEROctetString(createRandomBytes()));
146         pkiHeaderBuilder.setTransactionID(new DEROctetString(createRandomBytes()));
147         pkiHeaderBuilder.setProtectionAlg(protectionAlg);
148         pkiHeaderBuilder.setGeneralInfo(new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm));
149         pkiHeaderBuilder.setSenderKID(new DEROctetString(senderKid.getBytes()));
150
151         return pkiHeaderBuilder.build();
152     }
153 }