[POLICY-73] replace openecomp for policy-engine
[policy/engine.git] / ONAP-PDP / src / test / java / org / onap / policy / pdp / test / custom / FunctionDefinitionDecrypt.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PDP
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pdp.test.custom;
22
23 import java.security.InvalidKeyException;
24 import java.security.NoSuchAlgorithmException;
25 import java.security.PrivateKey;
26 import java.security.PublicKey;
27 import java.util.List;
28
29 import javax.crypto.BadPaddingException;
30 import javax.crypto.Cipher;
31 import javax.crypto.IllegalBlockSizeException;
32 import javax.crypto.NoSuchPaddingException;
33
34 import com.att.research.xacml.api.DataType;
35 import com.att.research.xacml.api.DataTypeException;
36 import com.att.research.xacml.api.Identifier;
37 import com.att.research.xacml.api.XACML3;
38 import com.att.research.xacml.std.IdentifierImpl;
39 import com.att.research.xacml.std.StdStatus;
40 import com.att.research.xacml.std.StdStatusCode;
41 import com.att.research.xacml.std.datatypes.DataTypeHexBinary;
42 import com.att.research.xacml.std.datatypes.DataTypeString;
43 import com.att.research.xacml.std.datatypes.HexBinary;
44 import com.att.research.xacmlatt.pdp.eval.EvaluationContext;
45 import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
46 import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
47 import com.att.research.xacmlatt.pdp.policy.FunctionDefinition;
48 import com.att.research.xacmlatt.pdp.std.functions.ConvertedArgument;
49
50 public class FunctionDefinitionDecrypt implements FunctionDefinition {
51         public static final Identifier FD_RSA_DECRYPT = new IdentifierImpl("urn:com:att:research:xacml:custom:function:3.0:rsa:decrypt");
52         private static final FunctionDefinitionDecrypt singleInstance = new FunctionDefinitionDecrypt();
53         
54         public static FunctionDefinitionDecrypt newInstance() {
55                 return singleInstance;
56         }
57
58         @Override
59         public Identifier getId() {
60                 return FD_RSA_DECRYPT;
61         }
62
63         @Override
64         public Identifier getDataTypeId() {
65                 return XACML3.ID_DATATYPE_STRING;
66         }
67
68         @Override
69         public boolean returnsBag() {
70                 return false;
71         }
72
73         @Override
74         public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) {
75                 if (arguments == null || arguments.size() < 2) {
76                         return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expecting 2 arguments."));
77                 }
78                 //
79                 // What is the first argument?
80                 //
81                 FunctionArgument arg0 = arguments.get(0);
82                 if (arg0.isBag()) {
83                         //
84                         // We don't support bags right now
85                         //
86                         return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not expecting a bag for argument 0."));
87                 }
88                 if (arg0.getValue().getDataTypeId().equals(XACML3.ID_DATATYPE_HEXBINARY) == false) {
89                         //
90                         // Should be a String
91                         //
92                         return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expected a Hex Binary for argument 0."));
93                 }
94                 //
95                 // Convert the argument
96                 //
97                 ConvertedArgument<HexBinary> data = new ConvertedArgument<HexBinary>(arg0, DataTypeHexBinary.newInstance(), false);
98                 if (! data.isOk()) {
99                         return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, argument 0 failed to convert to Hex Binary."));
100                 }
101                 //
102                 // Ok - check the 2nd argument
103                 //
104                 FunctionArgument arg1 = arguments.get(1);
105                 if (arg1.isBag()) {
106                         //
107                         // We don't support bags right now
108                         //
109                         return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, not expecting a bag for argument 1."));
110                 }
111                 if (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY) ||
112                                 arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
113                         //
114                         // Ok - let's try to decrypt
115                         //
116                         Cipher cipher;
117                         try {
118                                 cipher = Cipher.getInstance("RSA");
119                                 if (arg1.getValue().getDataTypeId().equals(DataTypePrivateKey.DT_PRIVATEKEY)) {
120                                         //
121                                         // Using the private key
122                                         //
123                                         DataType<PrivateKey> pkDatatype = DataTypePrivateKey.newInstance();
124                                         ConvertedArgument<PrivateKey> privateKey = new ConvertedArgument<PrivateKey>(arg1, pkDatatype, false);
125                                         if ( ! privateKey.isOk()) {
126                                                 return ExpressionResult.newError(new StdStatus(privateKey.getStatus().getStatusCode(), "Decrypt: " + privateKey.getStatus().getStatusMessage()));
127                                         }
128                                         //
129                                         // Setup decryption
130                                         //
131                                         cipher.init(Cipher.DECRYPT_MODE, privateKey.getValue());
132                                 } else if (arg1.getValue().getDataTypeId().equals(DataTypePublicKey.DT_PUBLICKEY)) {
133                                         //
134                                         // Using the private key
135                                         //
136                                         DataType<PublicKey> pkDatatype = DataTypePublicKey.newInstance();
137                                         ConvertedArgument<PublicKey> publicKey = new ConvertedArgument<PublicKey>(arg1, pkDatatype, false);
138                                         if ( ! publicKey.isOk()) {
139                                                 return ExpressionResult.newError(new StdStatus(publicKey.getStatus().getStatusCode(), "Decrypt: " + publicKey.getStatus().getStatusMessage()));
140                                         }
141                                         //
142                                         // Setup decryption
143                                         //
144                                         cipher.init(Cipher.DECRYPT_MODE, publicKey.getValue());
145                                 }
146                                 //
147                                 // Do the decryption
148                                 //
149                                 byte[] decryptedData = cipher.doFinal(data.getValue().getData());
150                                 String decryptedString = new String(decryptedData);
151                                 //
152                                 // All good, return the decrypted string
153                                 //
154                                 return ExpressionResult.newSingle(DataTypeString.newInstance().createAttributeValue(decryptedString));
155                         } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | DataTypeException e) {
156                                 return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed: " + e.getLocalizedMessage()));
157                         }
158                 }               
159                 return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Decrypt failed, expecting public/private key datatype for argument 1."));
160         }
161
162 }