blob: 58106371bd09943d1696d0f11d639e28e899f049 [file] [log] [blame]
NingSun0c89b3c2018-02-08 08:34:03 -08001/*
2 * Copyright (c) 2010 SURFnet bv
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27/*****************************************************************************
28 OSSLGOSTPublicKey.cpp
29
30 OpenSSL GOST R 34.10-2001 public key class
31 *****************************************************************************/
32
33#include "config.h"
34#ifdef WITH_GOST
35#include "log.h"
36#include "OSSLGOSTPublicKey.h"
37#include <openssl/x509.h>
38#include <string.h>
39
40// the 37 bytes of prefix
41const unsigned char gost_prefix[] = {
42 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
43 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07,
44 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06,
45 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01,
46 0x03, 0x43, 0x00, 0x04, 0x40
47};
48
49// Constructors
50OSSLGOSTPublicKey::OSSLGOSTPublicKey()
51{
52 pkey = EVP_PKEY_new();
53}
54
55OSSLGOSTPublicKey::OSSLGOSTPublicKey(const EVP_PKEY* inPKEY)
56{
57 OSSLGOSTPublicKey();
58
59 setFromOSSL(inPKEY);
60}
61
62// Destructor
63OSSLGOSTPublicKey::~OSSLGOSTPublicKey()
64{
65 EVP_PKEY_free(pkey);
66}
67
68// The type
69/*static*/ const char* OSSLGOSTPublicKey::type = "OpenSSL GOST Public Key";
70
71// Get the output length
72unsigned long OSSLGOSTPublicKey::getOutputLength() const
73{
74 return getQ().size();
75}
76
77// Set from OpenSSL representation
78void OSSLGOSTPublicKey::setFromOSSL(const EVP_PKEY* pkey)
79{
80 ByteString der;
81 int len = i2d_PUBKEY((EVP_PKEY*) pkey, NULL);
82 if (len != 37 + 64)
83 {
84 ERROR_MSG("bad GOST public key encoding length %d", len);
85 return;
86 }
87 der.resize(len);
88 unsigned char *p = &der[0];
89 i2d_PUBKEY((EVP_PKEY*) pkey, &p);
90 // can check: der is prefix + 64 bytes
91 setQ(der.substr(37));
92
93 ByteString inEC;
94 const EC_KEY* eckey = (const EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
95 int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
96 inEC.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL));
97 p = &inEC[0];
98 i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p);
99 setEC(inEC);
100}
101
102// Check if the key is of the given type
103bool OSSLGOSTPublicKey::isOfType(const char* inType)
104{
105 return !strcmp(type, inType);
106}
107
108// Setters for the GOST public key components
109void OSSLGOSTPublicKey::setEC(const ByteString& inEC)
110{
111 GOSTPublicKey::setEC(inEC);
112}
113
114void OSSLGOSTPublicKey::setQ(const ByteString& inQ)
115{
116 GOSTPublicKey::setQ(inQ);
117
118 if (inQ.size() != 64)
119 {
120 ERROR_MSG("bad GOST public key size %zu", q.size());
121 return;
122 }
123
124 ByteString der;
125 der.resize(37 + 64);
126 memcpy(&der[0], gost_prefix, 37);
127 memcpy(&der[37], inQ.const_byte_str(), 64);
128 const unsigned char *p = &der[0];
129 if (d2i_PUBKEY(&pkey, &p, (long) der.size()) == NULL)
130 ERROR_MSG("d2i_PUBKEY failed");
131}
132
133// Serialisation
134ByteString OSSLGOSTPublicKey::serialise() const
135{
136 return ec.serialise() +
137 q.serialise();
138}
139
140bool OSSLGOSTPublicKey::deserialise(ByteString& serialised)
141{
142 ByteString dEC = ByteString::chainDeserialise(serialised);
143 ByteString dQ = ByteString::chainDeserialise(serialised);
144
145 if ((dEC.size() == 0) ||
146 (dQ.size() == 0))
147 {
148 return false;
149 }
150
151 setEC(dEC);
152 setQ(dQ);
153
154 return true;
155}
156
157// Retrieve the OpenSSL representation of the key
158EVP_PKEY* OSSLGOSTPublicKey::getOSSLKey()
159{
160 return pkey;
161}
162#endif