1 /** 2 * EAC SIGNED Object 3 * 4 * Copyright: 5 * (C) 2007 FlexSecure GmbH 6 * 2008 Jack Lloyd 7 * (C) 2014-2015 Etienne Cimon 8 * 9 * License: 10 * Botan is released under the Simplified BSD License (see LICENSE.md) 11 */ 12 module botan.cert.cvc.signed_obj; 13 14 import botan.constants; 15 static if (BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES): 16 17 import botan.asn1.asn1_obj; 18 import botan.cert.x509.key_constraint; 19 import botan.pubkey.x509_key; 20 import botan.filters.pipe; 21 import botan.pubkey.pubkey; 22 import botan.asn1.oids; 23 import botan.utils.types; 24 import botan.utils.exceptn; 25 import botan.codec.pem; 26 import botan.utils.mem_ops; 27 28 import std.algorithm : splitter; 29 30 interface SignedObject { 31 /** 32 * Get the TBS (to-be-signed) data in this object. 33 * Returns: DER encoded TBS data of this object 34 */ 35 const(Vector!ubyte) tbsData() const; 36 37 /** 38 * Get the signature of this object as a concatenation, i.e. if the 39 * signature consists of multiple parts (like in the case of ECDSA) 40 * these will be concatenated. 41 * Returns: signature as a concatenation of its parts 42 */ 43 const(Vector!ubyte) getConcatSig() const; 44 /** 45 * Write this object DER encoded into a specified pipe. 46 * 47 * Params: 48 * pipe = the pipe to write the encoded object to 49 * encoding = the encoding type to use 50 */ 51 void encode(Pipe pipe, X509Encoding encoding = PEM_) const; 52 protected: 53 abstract void forceDecode(); 54 } 55 56 /** 57 * This class represents abstract signed EAC object 58 */ 59 abstract class EACSignedObject : SignedObject 60 { 61 public: 62 63 64 /** 65 * Get the signature algorithm identifier used to sign this object. 66 * Returns: the signature algorithm identifier 67 */ 68 const(AlgorithmIdentifier) signatureAlgorithm() const 69 { 70 return m_sig_algo; 71 } 72 73 /** 74 * Check the signature of this object. 75 * 76 * Params: 77 * pub_key = the public key associated with this signed object 78 * sig = the signature we are checking 79 * Returns: true if the signature was created by the private key 80 * associated with this public key 81 */ 82 bool checkSignature(ALLOC)(PublicKey pub_key, auto ref Vector!(ubyte, ALLOC) sig) const 83 { 84 try 85 { 86 Vector!string sig_info = splitter(OIDS.lookup(m_sig_algo.oid), '/'); 87 88 if (sig_info.length != 2 || sig_info[0] != pub_key.algoName) 89 { 90 return false; 91 } 92 93 string padding = sig_info[1]; 94 SignatureFormat format = (pub_key.messageParts() >= 2) ? DER_SEQUENCE : IEEE_1363; 95 96 const(Vector!ubyte) to_sign = tbsData(); 97 98 PKVerifier verifier = PKVerifier(pub_key, padding, format); 99 return verifier.verifyMessage(to_sign, sig); 100 } 101 catch (Exception) 102 { 103 return false; 104 } 105 } 106 107 108 109 /** 110 * BER encode this object. 111 * Returns: result containing the BER representation of this object. 112 */ 113 Vector!ubyte BER_encode() const 114 { 115 Pipe ber; 116 ber.startMsg(); 117 encode(ber, RAW_BER); 118 ber.endMsg(); 119 return unlock(ber.readAll()); 120 } 121 122 /** 123 * PEM encode this object. 124 * Returns: result containing the PEM representation of this object. 125 */ 126 string PEM_encode() const 127 { 128 Pipe pem; 129 pem.startMsg(); 130 encode(pem, PEM_); 131 pem.endMsg(); 132 return pem.toString(); 133 } 134 135 ~this() {} 136 protected: 137 138 /* 139 * Try to decode the actual information 140 */ 141 void doDecode() 142 { 143 try { 144 forceDecode(); 145 } 146 catch(DecodingError e) 147 { 148 const string what = e.msg; 149 throw new DecodingError("EACSignedObject decoding failed (" ~ what ~ ")"); 150 } 151 catch(InvalidArgument e) 152 { 153 const string what = e.msg; 154 throw new DecodingError("EACSignedObject decoding failed (" ~ what ~ ")"); 155 } 156 } 157 158 this() {} 159 160 AlgorithmIdentifier m_sig_algo; 161 Vector!ubyte m_tbs_bits; 162 string[] m_PEM_labels_allowed; 163 }