monotone

monotone Mtn Source Tree

Root/botan/x509_key.cpp

1/*************************************************
2* X.509 Public Key Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/x509_key.h>
7#include <botan/filters.h>
8#include <botan/asn1_obj.h>
9#include <botan/pk_algs.h>
10#include <botan/oids.h>
11#include <botan/pem.h>
12#include <memory>
13
14namespace Botan {
15
16/*************************************************
17* Compute the key id *
18*************************************************/
19u64bit X509_PublicKey::key_id() const
20 {
21 Pipe pipe(new Hash_Filter("SHA-1", 8));
22
23 pipe.start_msg();
24 pipe.write(algo_name());
25 pipe.write(DER_encode_pub());
26 pipe.write(DER_encode_params());
27 pipe.end_msg();
28
29 u64bit hash = 0;
30 for(u32bit j = 0; j != 8; j++)
31 {
32 byte next = 0;
33 if(pipe.read(next) != 1)
34 throw Internal_Error("X509_PublicKey::key_id: No more hash bits");
35 hash = (hash << 8) | next;
36 }
37 return hash;
38 }
39
40namespace X509 {
41
42namespace {
43
44/*************************************************
45* Extract the fields of a subjectPublicKeyInfo *
46*************************************************/
47void X509_extract_info(DataSource& source, AlgorithmIdentifier& alg_id,
48 MemoryVector<byte>& key)
49 {
50 BER_Decoder decoder(source);
51 BER_Decoder sequence = BER::get_subsequence(decoder);
52 BER::decode(sequence, alg_id);
53 BER::decode(sequence, key, BIT_STRING);
54 sequence.verify_end();
55 }
56
57}
58
59/*************************************************
60* DER or PEM encode a X.509 public key *
61*************************************************/
62void encode(const X509_PublicKey& key, Pipe& pipe, X509_Encoding encoding)
63 {
64 DER_Encoder encoder;
65 AlgorithmIdentifier alg_id(key.get_oid(), key.DER_encode_params());
66
67 encoder.start_sequence();
68 DER::encode(encoder, alg_id);
69 DER::encode(encoder, key.DER_encode_pub(), BIT_STRING);
70 encoder.end_sequence();
71
72 MemoryVector<byte> der = encoder.get_contents();
73 if(encoding == PEM)
74 pipe.write(PEM_Code::encode(der, "PUBLIC KEY"));
75 else
76 pipe.write(der);
77 }
78
79/*************************************************
80* PEM encode a X.509 public key *
81*************************************************/
82std::string PEM_encode(const X509_PublicKey& key)
83 {
84 Pipe pem;
85 pem.start_msg();
86 encode(key, pem, PEM);
87 pem.end_msg();
88 return pem.read_all_as_string();
89 }
90
91/*************************************************
92* Extract a public key and return it *
93*************************************************/
94X509_PublicKey* load_key(DataSource& source)
95 {
96 try {
97 AlgorithmIdentifier alg_id;
98 MemoryVector<byte> key;
99
100 if(BER::maybe_BER(source) && !PEM_Code::matches(source))
101 X509_extract_info(source, alg_id, key);
102 else
103 {
104 DataSource_Memory ber(
105 PEM_Code::decode_check_label(source, "PUBLIC KEY")
106 );
107 X509_extract_info(ber, alg_id, key);
108 }
109
110 if(key.is_empty())
111 throw Decoding_Error("X.509 public key decoding failed");
112
113 const std::string alg_name = OIDS::lookup(alg_id.oid);
114 if(alg_name == "")
115 throw Decoding_Error("Unknown algorithm OID: " +
116 alg_id.oid.as_string());
117
118 std::auto_ptr<X509_PublicKey> key_obj(get_public_key(alg_name));
119 if(!key_obj.get())
120 throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " +
121 alg_id.oid.as_string());
122
123 Pipe output;
124 output.process_msg(alg_id.parameters);
125 output.process_msg(key);
126 key_obj->BER_decode_params(output);
127 output.set_default_msg(1);
128 key_obj->BER_decode_pub(output);
129
130 return key_obj.release();
131 }
132 catch(Decoding_Error)
133 {
134 throw Decoding_Error("X.509 public key decoding failed");
135 }
136 }
137
138/*************************************************
139* Extract a public key and return it *
140*************************************************/
141X509_PublicKey* load_key(const std::string& fsname)
142 {
143 DataSource_Stream source(fsname, true);
144 return X509::load_key(source);
145 }
146
147/*************************************************
148* Extract a public key and return it *
149*************************************************/
150X509_PublicKey* load_key(const MemoryRegion<byte>& mem)
151 {
152 DataSource_Memory source(mem);
153 return X509::load_key(source);
154 }
155
156/*************************************************
157* Make a copy of this public key *
158*************************************************/
159X509_PublicKey* copy_key(const X509_PublicKey& key)
160 {
161 Pipe bits;
162 bits.start_msg();
163 X509::encode(key, bits, RAW_BER);
164 bits.end_msg();
165 DataSource_Memory source(bits.read_all());
166 return X509::load_key(source);
167 }
168
169/*************************************************
170* Find the allowable key constraints *
171*************************************************/
172Key_Constraints find_constraints(const X509_PublicKey& pub_key,
173 Key_Constraints limits)
174 {
175 const X509_PublicKey* key = &pub_key;
176 u32bit constraints = 0;
177
178 if(dynamic_cast<const PK_Encrypting_Key*>(key))
179 constraints |= KEY_ENCIPHERMENT;
180
181 if(dynamic_cast<const PK_Key_Agreement_Key*>(key))
182 constraints |= KEY_AGREEMENT;
183
184 if(dynamic_cast<const PK_Verifying_wo_MR_Key*>(key) ||
185 dynamic_cast<const PK_Verifying_with_MR_Key*>(key))
186 constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION;
187
188 if(limits)
189 constraints &= limits;
190
191 return Key_Constraints(constraints);
192 }
193
194}
195
196}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status