monotone

monotone Mtn Source Tree

Root/botan/x509_key.cpp

1/*************************************************
2* X.509 Public Key Source File *
3* (C) 1999-2006 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/der_enc.h>
10#include <botan/ber_dec.h>
11#include <botan/pk_algs.h>
12#include <botan/oids.h>
13#include <botan/pem.h>
14#include <memory>
15
16namespace Botan {
17
18namespace X509 {
19
20/*************************************************
21* DER or PEM encode a X.509 public key *
22*************************************************/
23void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding)
24 {
25 std::auto_ptr<X509_Encoder> encoder(key.x509_encoder());
26 if(!encoder.get())
27 throw Encoding_Error("X509::encode: Key does not support encoding");
28
29 MemoryVector<byte> der =
30 DER_Encoder()
31 .start_cons(SEQUENCE)
32 .encode(encoder->alg_id())
33 .encode(encoder->key_bits(), BIT_STRING)
34 .end_cons()
35 .get_contents();
36
37 if(encoding == PEM)
38 pipe.write(PEM_Code::encode(der, "PUBLIC KEY"));
39 else
40 pipe.write(der);
41 }
42
43/*************************************************
44* PEM encode a X.509 public key *
45*************************************************/
46std::string PEM_encode(const Public_Key& key)
47 {
48 Pipe pem;
49 pem.start_msg();
50 encode(key, pem, PEM);
51 pem.end_msg();
52 return pem.read_all_as_string();
53 }
54
55/*************************************************
56* Extract a public key and return it *
57*************************************************/
58Public_Key* load_key(DataSource& source)
59 {
60 try {
61 AlgorithmIdentifier alg_id;
62 MemoryVector<byte> key_bits;
63
64 if(ASN1::maybe_BER(source) && !PEM_Code::matches(source))
65 {
66 BER_Decoder(source)
67 .start_cons(SEQUENCE)
68 .decode(alg_id)
69 .decode(key_bits, BIT_STRING)
70 .verify_end()
71 .end_cons();
72 }
73 else
74 {
75 DataSource_Memory ber(
76 PEM_Code::decode_check_label(source, "PUBLIC KEY")
77 );
78
79 BER_Decoder(ber)
80 .start_cons(SEQUENCE)
81 .decode(alg_id)
82 .decode(key_bits, BIT_STRING)
83 .verify_end()
84 .end_cons();
85 }
86
87 if(key_bits.is_empty())
88 throw Decoding_Error("X.509 public key decoding failed");
89
90 const std::string alg_name = OIDS::lookup(alg_id.oid);
91 if(alg_name == "")
92 throw Decoding_Error("Unknown algorithm OID: " +
93 alg_id.oid.as_string());
94
95 std::auto_ptr<Public_Key> key_obj(get_public_key(alg_name));
96 if(!key_obj.get())
97 throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " +
98 alg_id.oid.as_string());
99
100 std::auto_ptr<X509_Decoder> decoder(key_obj->x509_decoder());
101 if(!decoder.get())
102 throw Decoding_Error("Key does not support X.509 decoding");
103
104 decoder->alg_id(alg_id);
105 decoder->key_bits(key_bits);
106
107 return key_obj.release();
108 }
109 catch(Decoding_Error)
110 {
111 throw Decoding_Error("X.509 public key decoding failed");
112 }
113 }
114
115/*************************************************
116* Extract a public key and return it *
117*************************************************/
118Public_Key* load_key(const std::string& fsname)
119 {
120 DataSource_Stream source(fsname, true);
121 return X509::load_key(source);
122 }
123
124/*************************************************
125* Extract a public key and return it *
126*************************************************/
127Public_Key* load_key(const MemoryRegion<byte>& mem)
128 {
129 DataSource_Memory source(mem);
130 return X509::load_key(source);
131 }
132
133/*************************************************
134* Make a copy of this public key *
135*************************************************/
136Public_Key* copy_key(const Public_Key& key)
137 {
138 Pipe bits;
139 bits.start_msg();
140 X509::encode(key, bits, RAW_BER);
141 bits.end_msg();
142 DataSource_Memory source(bits.read_all());
143 return X509::load_key(source);
144 }
145
146/*************************************************
147* Find the allowable key constraints *
148*************************************************/
149Key_Constraints find_constraints(const Public_Key& pub_key,
150 Key_Constraints limits)
151 {
152 const Public_Key* key = &pub_key;
153 u32bit constraints = 0;
154
155 if(dynamic_cast<const PK_Encrypting_Key*>(key))
156 constraints |= KEY_ENCIPHERMENT;
157
158 if(dynamic_cast<const PK_Key_Agreement_Key*>(key))
159 constraints |= KEY_AGREEMENT;
160
161 if(dynamic_cast<const PK_Verifying_wo_MR_Key*>(key) ||
162 dynamic_cast<const PK_Verifying_with_MR_Key*>(key))
163 constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION;
164
165 if(limits)
166 constraints &= limits;
167
168 return Key_Constraints(constraints);
169 }
170
171}
172
173}

Archive Download this file

Branches

Tags

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