• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 package software.amazon.awssdk.crt.cal;
16 
17 import software.amazon.awssdk.crt.auth.credentials.Credentials;
18 import software.amazon.awssdk.crt.CrtResource;
19 
20 import java.util.HashMap;
21 import java.util.Map;
22 
23 /**
24  * This class puts an opaque wrapper around aws_ecc_key_pair from aws-c-cal.  Currently, it is only intended to be
25  * cached and returned to native code by a signing invocation.
26  *
27  * If there's a compelling reason, we can add accessors and conversions to/from Java's KeyPair.
28  */
29 public final class EccKeyPair extends CrtResource {
30 
31     /**
32      * Enum for supported ECC curves
33      * Needs to stay in sync with aws_ecc_curve_name
34      */
35     public enum AwsEccCurve {
36         /** Nist standard P256 elliptic curve */
37         AWS_ECDSA_P256(0),
38 
39         /** Nist standard P384 elliptic curve */
40         AWS_ECDSA_P384(1);
41 
42         /**
43          * Constructs a Java enum value from a native enum value as an integer
44          * @param nativeValue native enum value
45          */
AwsEccCurve(int nativeValue)46         AwsEccCurve(int nativeValue) {
47             this.nativeValue = nativeValue;
48         }
49 
50         /**
51          * Gets the native enum value as an integer that is associated with this Java enum value
52          * @return this value's associated native enum value
53          */
getNativeValue()54         public int getNativeValue() { return nativeValue; }
55 
56         /**
57          * Creates a Java enum value from a native enum value as an integer
58          * @param value native enum value
59          * @return the corresponding Java enum value
60          */
getEnumValueFromInteger(int value)61         public static AwsEccCurve getEnumValueFromInteger(int value) {
62             AwsEccCurve enumValue = enumMapping.get(value);
63             if (enumValue != null) {
64                 return enumValue;
65             }
66 
67             throw new RuntimeException("Illegal ecc curve name value");
68         }
69 
buildEnumMapping()70         private static Map<Integer, AwsEccCurve> buildEnumMapping() {
71             Map<Integer, AwsEccCurve> enumMapping = new HashMap<Integer, AwsEccCurve>();
72             enumMapping.put(AWS_ECDSA_P256.getNativeValue(), AWS_ECDSA_P256);
73             enumMapping.put(AWS_ECDSA_P384.getNativeValue(), AWS_ECDSA_P384);
74 
75             return enumMapping;
76         }
77 
78         private int nativeValue;
79 
80         private static Map<Integer, AwsEccCurve> enumMapping = buildEnumMapping();
81     }
82 
83     /**
84      * Creates a new ecc key pair.  Only called from native at the moment.
85      *
86      * @param nativeHandle handle to the native ecc key pair object
87      */
EccKeyPair(long nativeHandle)88     private EccKeyPair(long nativeHandle) {
89         acquireNativeHandle(nativeHandle);
90     }
91 
92     /**
93      * Determines whether a resource releases its dependencies at the same time the native handle is released or if it waits.
94      * Resources that wait are responsible for calling releaseReferences() manually.
95      */
96     @Override
canReleaseReferencesImmediately()97     protected boolean canReleaseReferencesImmediately() { return true; }
98 
99     /**
100      * Releases the instance's reference to the underlying native key pair
101      */
102     @Override
releaseNativeHandle()103     protected void releaseNativeHandle() {
104         if (!isNull()) {
105             eccKeyPairRelease(getNativeHandle());
106         }
107     }
108 
109     /**
110      * Derives the associated ECC key from a pair of AWS credentials according to the sigv4a ecc key
111      * derivation specification.
112      *
113      * @param credentials AWS credentials to derive the associated key for
114      * @param curve ECC curve to use (only P256 is currently supported)
115      * @return derived ecc key pair associated with the AWS credentials
116      */
newDeriveFromCredentials(Credentials credentials, AwsEccCurve curve)117     static public EccKeyPair newDeriveFromCredentials(Credentials credentials, AwsEccCurve curve) {
118         long nativeHandle = eccKeyPairNewFromCredentials(credentials, curve.getNativeValue());
119         if (nativeHandle != 0) {
120             return new EccKeyPair(nativeHandle);
121         }
122 
123         return null;
124     }
125 
126     /**
127      * Sign a message using the ECC key pair via ECDSA
128      * @param message message to sign
129      * @return the ECDSA signature of the message
130      */
signMessage(byte[] message)131     public byte[] signMessage(byte[] message) {
132         return eccKeyPairSignMessage(getNativeHandle(), message);
133     }
134 
135     /*******************************************************************************
136      * native methods
137      ******************************************************************************/
eccKeyPairNewFromCredentials(Credentials credentials, int curve)138     private static native long eccKeyPairNewFromCredentials(Credentials credentials, int curve);
eccKeyPairRelease(long ecc_key_pair)139     private static native void eccKeyPairRelease(long ecc_key_pair);
140 
eccKeyPairSignMessage(long ecc_key_pair, byte[] message)141     private static native byte[] eccKeyPairSignMessage(long ecc_key_pair, byte[] message);
142 };
143