blob: c1cb84ddb1c9c477e1ae194fdf6ef891a81fbd15 [file] [log] [blame]
Jeff Thompsonc0573432013-09-19 17:41:36 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
Alexander Afanasyev736708b2014-01-06 14:45:34 -08009#if __clang__
10#pragma clang diagnostic push
11#pragma clang diagnostic ignored "-Wreorder"
12#pragma clang diagnostic ignored "-Wtautological-compare"
13#pragma clang diagnostic ignored "-Wunused-variable"
14#pragma clang diagnostic ignored "-Wunused-function"
15#elif __GNUC__
16#pragma GCC diagnostic ignored "-Wreorder"
Alexander Afanasyev736708b2014-01-06 14:45:34 -080017#pragma GCC diagnostic ignored "-Wunused-variable"
18#pragma GCC diagnostic ignored "-Wunused-function"
19#endif
20
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080021#include "common.hpp"
22#include "security/public-key.hpp"
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080023
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080024#include <cryptopp/rsa.h>
25#include <cryptopp/base64.h>
26#include <cryptopp/files.h>
Jeff Thompsonc0573432013-09-19 17:41:36 -070027
28using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080029using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070030
31namespace ndn {
32
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080033static OID RSA_OID("1.2.840.113549.1.1.1");
Jeff Thompsonc0573432013-09-19 17:41:36 -070034
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080035PublicKey::PublicKey()
36{
Jeff Thompsonc0573432013-09-19 17:41:36 -070037}
Jeff Thompsonc0573432013-09-19 17:41:36 -070038
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080039/**
40 * Create a new PublicKey with the given values.
41 * @param algorithm The algorithm of the public key.
42 * @param keyDer The blob of the PublicKeyInfo in terms of DER.
43 */
44PublicKey::PublicKey(const uint8_t *keyDerBuf, size_t keyDerSize)
Jeff Thompsonc0573432013-09-19 17:41:36 -070045{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080046 StringSource src(keyDerBuf, keyDerSize, true);
47 decode(src);
Jeff Thompsonc0573432013-09-19 17:41:36 -070048}
49
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080050void
51PublicKey::encode(CryptoPP::BufferedTransformation &out) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070052{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080053 // SubjectPublicKeyInfo ::= SEQUENCE {
54 // algorithm AlgorithmIdentifier
55 // keybits BIT STRING }
56
57 out.Put(key_.buf(), key_.size());
58}
59
60void
61PublicKey::decode(CryptoPP::BufferedTransformation &in)
62{
63 // SubjectPublicKeyInfo ::= SEQUENCE {
64 // algorithm AlgorithmIdentifier
65 // keybits BIT STRING }
66
67 try {
68 std::string out;
69 StringSink sink(out);
70
71 ////////////////////////
72 // part 1: copy as is //
73 ////////////////////////
74 BERSequenceDecoder decoder(in);
75 {
76 assert (decoder.IsDefiniteLength());
77
78 DERSequenceEncoder encoder(sink);
79 decoder.TransferTo(encoder, decoder.RemainingLength());
80 encoder.MessageEnd();
81 }
82 decoder.MessageEnd();
83
84 ////////////////////////
85 // part 2: check if the key is RSA (since it is the only supported for now)
86 ////////////////////////
87 StringSource checkedSource(out, true);
88 BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
89 {
90 BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
91 {
92 OID algorithm;
93 algorithm.decode(algorithmInfo);
94
95 if (algorithm != RSA_OID)
96 throw Error("Only RSA public keys are supported for now (" + algorithm.toString() + " requested");
97 }
98 }
99
100 key_.assign(out.begin(), out.end());
Jeff Thompsonc0573432013-09-19 17:41:36 -0700101 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800102 catch (CryptoPP::BERDecodeErr &err) {
103 throw Error("PublicKey decoding error");
104 }
105}
106
107// Blob
108// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
109// {
110// if (digestAlgorithm == DIGEST_ALGORITHM_SHA256) {
111// uint8_t digest[SHA256_DIGEST_LENGTH];
112// ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
113
114// return Blob(digest, sizeof(digest));
115// }
116// else
117// throw UnrecognizedDigestAlgorithmException("Wrong format!");
118// }
119
120std::ostream &
121operator <<(std::ostream &os, const PublicKey &key)
122{
123 CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
124 new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
125
126 return os;
Jeff Thompsonc0573432013-09-19 17:41:36 -0700127}
128
129}