1 /** 2 * EAC11 CVC Request 3 * 4 * Copyright: 5 * (C) 2008 Falko Strenzke 6 * 2010 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.cvc_req; 13 14 import botan.constants; 15 static if (BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES): 16 17 import botan.cert.cvc.cvc_gen_cert; 18 import botan.asn1.oids; 19 import botan.asn1.ber_dec; 20 import botan.utils.types; 21 import botan.cert.cvc.cvc_cert; 22 import botan.cert.cvc.ecdsa_sig; 23 import botan.cert.cvc.signed_obj; 24 import botan.filters.pipe; 25 import botan.pubkey.x509_key; 26 import botan.pubkey.algo.ecdsa; 27 28 alias EAC11Req = RefCounted!EAC11ReqImpl; 29 /** 30 * This class represents TR03110 v1.1 EAC CV Certificate Requests. 31 */ 32 final class EAC11ReqImpl : EAC11genCVC!EAC11ReqImpl, SignedObject 33 { 34 public: 35 36 /** 37 * Compare for equality with other 38 * Params: 39 * rhs = compare for equality with this object 40 */ 41 bool opEquals(in EAC11Req rhs) const 42 { 43 return (this.tbsData() == rhs.tbsData() && 44 this.getConcatSig() == rhs.getConcatSig()); 45 } 46 47 int opCmp(in EAC11ReqImpl rhs) const 48 { 49 if (this == rhs) 50 return 0; 51 else return -1; 52 53 } 54 /** 55 * Construct a CVC request from a data source. 56 * 57 * Params: 58 * source = the data source 59 */ 60 this(DataSource source) 61 { 62 init(source); 63 m_self_signed = true; 64 doDecode(); 65 } 66 67 /** 68 * Construct a CVC request from a DER encoded CVC request file. 69 * 70 * Params: 71 * str = the path to the DER encoded file 72 */ 73 this(in string str) 74 { 75 auto stream = DataSourceStream(str, true); 76 init(cast(DataSource)stream); 77 m_self_signed = true; 78 doDecode(); 79 } 80 81 // copy 82 this(const ref EAC11Req other) 83 { 84 m_sig = other.m_sig.clone; 85 m_sig_algo = AlgorithmIdentifier(other.m_sig_algo); 86 m_tbs_bits = other.m_tbs_bits.clone; 87 m_PEM_labels_allowed = other.m_PEM_labels_allowed.clone; 88 89 m_pk = cast(ECDSAPublicKey)other.m_pk; // no copy of this... 90 m_chr = ASN1Chr(other.m_chr); 91 m_self_signed = other.m_self_signed; 92 } 93 94 // assign 95 void opAssign(ref EAC11Req other) { 96 m_sig = other.m_sig; 97 m_sig_algo = other.m_sig_algo; 98 m_tbs_bits = other.m_tbs_bits.clone; // move? 99 m_PEM_labels_allowed = other.m_PEM_labels_allowed; 100 m_pk = other.m_pk; 101 m_chr = other.m_chr; 102 m_self_signed = other.m_self_signed; 103 } 104 105 // Interface fall-through 106 override const(Vector!ubyte) getConcatSig() const { return super.getConcatSig(); } 107 override void encode(Pipe pipe, X509Encoding encoding = PEM_) const { return super.encode(pipe, encoding); } 108 override const(Vector!ubyte) tbsData() const { return super.tbsData(); } 109 110 protected: 111 override void forceDecode() 112 { 113 Vector!ubyte enc_pk; 114 BERDecoder tbs_cert = BERDecoder(m_tbs_bits); 115 size_t cpi; 116 tbs_cert.decode(cpi, (cast(ASN1Tag)41), ASN1Tag.APPLICATION) 117 .startCons((cast(ASN1Tag)73), ASN1Tag.APPLICATION) 118 .rawBytes(enc_pk) 119 .endCons() 120 .decode(m_chr) 121 .verifyEnd(); 122 123 if (cpi != 0) 124 throw new DecodingError("EAC1_1 requests cpi was not 0"); 125 126 m_pk = decodeEac11Key(enc_pk, m_sig_algo); 127 } 128 }