@@ -44,10 +44,18 @@ public TagValue(int tagIn, ArrayList<TagValue> listIn) {
4444 // 1.2.840.10045.2.1
4545 public static final byte [] oid_ecPublicKey = new byte []{0x06 , 0x07 , 0x2a , (byte ) 0x86 , 0x48 , (byte ) 0xce , 0x3d , 0x2 , 0x1 };
4646
47+ // 1.3.101.110
48+ public static final byte [] Oid_X25519 = new byte []{0x6 , 3 , 0x2b , 101 , 110 };
49+ // 1.3.101.111
50+ public static final byte [] Oid_X448 = new byte []{0x6 , 3 , 0x2b , 101 , 111 };
51+ // 1.3.101.112
52+ public static final byte [] Oid_Ed25519 = new byte []{0x6 , 0x3 , 0x2b , 101 , 112 };
53+ // 1.3.101.113
54+ public static final byte [] Oid_Ed448 = new byte []{0x6 , 0x3 , 0x2b , 101 , 113 };
4755
48- private static final byte [] SequenceX = new byte []{0x30 };
49- private static final byte [] BitstringTag = new byte []{0x3 };
50- private static final byte [] OctetstringTag = new byte []{0x4 };
56+ private static final byte [] SequenceTag = new byte []{0x30 };
57+ private static final byte [] OctetStringTag = new byte []{0x4 };
58+ private static final byte [] BitStringTag = new byte []{0x3 };
5159
5260 /**
5361 * Encode a subject public key info structure from an OID and the data bytes
@@ -58,7 +66,7 @@ public TagValue(int tagIn, ArrayList<TagValue> listIn) {
5866 * @param keyBytes - encoded key bytes
5967 * @return - encoded SPKI
6068 */
61- public static byte [] EncodeSubjectPublicKeyInfo (byte [] oid , byte [] keyBytes ) throws CoseException
69+ public static byte [] EncodeSubjectPublicKeyInfo (byte [] algorithm , byte [] keyBytes ) throws CoseException
6270 {
6371 // SPKI ::= SEQUENCE {
6472 // algorithm SEQUENCE {
@@ -68,9 +76,9 @@ public static byte[] EncodeSubjectPublicKeyInfo(byte[] oid, byte[] keyBytes) thr
6876 // subjectPublicKey BIT STRING CONTAINS key bytes
6977 // }
7078 try {
71- ArrayList <byte []> xxx = new ArrayList <>();
72- xxx .add (AlgorithmIdentifier ( oid_ecPublicKey , oid ) );
73- xxx .add (BitstringTag );
79+ ArrayList <byte []> xxx = new ArrayList <byte [] >();
80+ xxx .add (algorithm );
81+ xxx .add (new byte []{ 3 } );
7482 xxx .add (ComputeLength (keyBytes .length +1 ));
7583 xxx .add (new byte []{0 });
7684 xxx .add (keyBytes );
@@ -84,6 +92,44 @@ public static byte[] EncodeSubjectPublicKeyInfo(byte[] oid, byte[] keyBytes) thr
8492 }
8593
8694 /**
95+ * Encode an EC Private key
96+ * @param oid - curve to use
97+ * @param keyBytes - bytes of the key
98+ * @param spki - optional SPKI
99+ * @return
100+ * @throws CoseException
101+ */
102+ public static byte [] EncodeEcPrivateKey (byte [] oid , byte [] keyBytes , byte [] spki ) throws CoseException
103+ {
104+ // ECPrivateKey ::= SEQUENCE {
105+ // version INTEGER {1}
106+ // privateKey OCTET STRING
107+ // parameters [0] OBJECT IDENTIFIER = named curve
108+ // public key [1] BIT STRING OPTIONAL
109+ // }
110+ //
111+
112+ ArrayList <byte []> xxx = new ArrayList <byte []>();
113+ xxx .add (new byte []{2 , 1 , 1 });
114+ xxx .add (OctetStringTag );
115+ xxx .add (ComputeLength (keyBytes .length ));
116+ xxx .add (keyBytes );
117+ xxx .add (new byte []{(byte )0xa0 });
118+ xxx .add (ComputeLength (oid .length ));
119+ xxx .add (oid );
120+ if (spki != null ) {
121+ xxx .add (new byte []{(byte )0xa1 });
122+ xxx .add (ComputeLength (spki .length +1 ));
123+ xxx .add (new byte []{0 });
124+ xxx .add (spki );
125+ }
126+
127+ byte [] ecPrivateKey = Sequence (xxx );
128+
129+ return ecPrivateKey ;
130+ }
131+
132+ /*
87133 * Decode an object which is supposed to be a SubjectPublicKeyInfo strucuture
88134 * and check that the right set of fields are in the right place
89135 *
@@ -174,15 +220,8 @@ public static TagValue DecodeCompound(int offset, byte[] encoding) throws CoseEx
174220 * @return byte array of encoded bytes
175221 * @throws CoseException
176222 */
177- public static byte [] EncodePKCS8 (byte [] oid , byte [] keyBytes , byte [] spki ) throws CoseException
223+ public static byte [] EncodePKCS8 (byte [] algorithm , byte [] keyBytes , byte [] spki ) throws CoseException
178224 {
179- // ECPrivateKey ::= SEQUENCE {
180- // version INTEGER {1}
181- // privateKey OCTET STRING
182- // parameters [0] OBJECT IDENTIFIER = named curve
183- // public key [1] BIT STRING OPTIONAL
184- // }
185- //
186225 // PKCS#8 ::= SEQUENCE {
187226 // version INTEGER {0}
188227 // privateKeyALgorithm SEQUENCE {
@@ -195,29 +234,13 @@ public static byte[] EncodePKCS8(byte[] oid, byte[] keyBytes, byte[] spki) throw
195234 // }
196235
197236 try {
198- ArrayList <byte []> xxx = new ArrayList <byte []>();
199- xxx .add (new byte []{2 , 1 , 1 });
200- xxx .add (OctetstringTag );
201- xxx .add (ComputeLength (keyBytes .length ));
202- xxx .add (keyBytes );
203- xxx .add (new byte []{(byte )0xa0 });
204- xxx .add (ComputeLength (oid .length ));
205- xxx .add (oid );
206- if (spki != null ) {
207- xxx .add (new byte []{(byte )0xa1 });
208- xxx .add (ComputeLength (spki .length +1 ));
209- xxx .add (new byte []{0 });
210- xxx .add (spki );
211- }
212-
213- byte [] ecPrivateKey = Sequence (xxx );
214237
215- xxx = new ArrayList <byte []>();
238+ ArrayList < byte []> xxx = new ArrayList <byte []>();
216239 xxx .add (new byte []{2 , 1 , 0 });
217- xxx .add (AlgorithmIdentifier ( oid_ecPublicKey , oid ) );
218- xxx .add (OctetstringTag );
219- xxx .add (ComputeLength (ecPrivateKey .length ));
220- xxx .add (ecPrivateKey );
240+ xxx .add (algorithm );
241+ xxx .add (OctetStringTag );
242+ xxx .add (ComputeLength (keyBytes .length ));
243+ xxx .add (keyBytes );
221244
222245 return Sequence (xxx );
223246 }
@@ -294,7 +317,6 @@ public static ArrayList<TagValue> DecodePKCS8(byte[] encodedData) throws CoseExc
294317 return retValue ;
295318 }
296319
297-
298320 public static byte [] EncodeSignature (byte [] r , byte [] s ) throws CoseException {
299321 ArrayList <byte []> x = new ArrayList <byte []>();
300322 x .add (UnsignedInteger (r ));
@@ -303,7 +325,16 @@ public static byte[] EncodeSignature(byte[] r, byte[] s) throws CoseException {
303325 return Sequence (x );
304326 }
305327
306- private static byte [] AlgorithmIdentifier (byte [] oid , byte [] params ) throws CoseException
328+ public static byte [] EncodeOctetString (byte [] data ) throws CoseException {
329+ ArrayList <byte []> x = new ArrayList <byte []>();
330+ x .add (OctetStringTag );
331+ x .add (ComputeLength (data .length ));
332+ x .add (data );
333+
334+ return ToBytes (x );
335+ }
336+
337+ public static byte [] AlgorithmIdentifier (byte [] oid , byte [] params ) throws CoseException
307338 {
308339 ArrayList <byte []> xxx = new ArrayList <byte []>();
309340 xxx .add (oid );
@@ -312,16 +343,18 @@ private static byte[] AlgorithmIdentifier(byte[] oid, byte[] params) throws Cose
312343 }
313344 return Sequence (xxx );
314345 }
346+
315347 private static byte [] Sequence (ArrayList <byte []> members ) throws CoseException
316348 {
317349 byte [] y = ToBytes (members );
318350 ArrayList <byte []> x = new ArrayList <byte []>();
319- x .add (SequenceX );
351+ x .add (SequenceTag );
320352 x .add (ComputeLength (y .length ));
321353 x .add (y );
322354
323355 return ToBytes (x );
324356 }
357+
325358 private static byte [] UnsignedInteger (byte [] i ) throws CoseException {
326359 int pad = 0 , offset = 0 ;
327360
0 commit comments