Botan
1.11.15
|
00001 /* 00002 * PKCS #10 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/pkcs10.h> 00009 #include <botan/x509_ext.h> 00010 #include <botan/x509cert.h> 00011 #include <botan/der_enc.h> 00012 #include <botan/ber_dec.h> 00013 #include <botan/parsing.h> 00014 #include <botan/oids.h> 00015 #include <botan/pem.h> 00016 00017 namespace Botan { 00018 00019 /* 00020 * PKCS10_Request Constructor 00021 */ 00022 PKCS10_Request::PKCS10_Request(DataSource& in) : 00023 X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST") 00024 { 00025 do_decode(); 00026 } 00027 00028 /* 00029 * PKCS10_Request Constructor 00030 */ 00031 PKCS10_Request::PKCS10_Request(const std::string& in) : 00032 X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST") 00033 { 00034 do_decode(); 00035 } 00036 00037 /* 00038 * PKCS10_Request Constructor 00039 */ 00040 PKCS10_Request::PKCS10_Request(const std::vector<byte>& in) : 00041 X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST") 00042 { 00043 do_decode(); 00044 } 00045 00046 /* 00047 * Deocde the CertificateRequestInfo 00048 */ 00049 void PKCS10_Request::force_decode() 00050 { 00051 BER_Decoder cert_req_info(tbs_bits); 00052 00053 size_t version; 00054 cert_req_info.decode(version); 00055 if(version != 0) 00056 throw Decoding_Error("Unknown version code in PKCS #10 request: " + 00057 std::to_string(version)); 00058 00059 X509_DN dn_subject; 00060 cert_req_info.decode(dn_subject); 00061 00062 info.add(dn_subject.contents()); 00063 00064 BER_Object public_key = cert_req_info.get_next_object(); 00065 if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED) 00066 throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key", 00067 public_key.type_tag, public_key.class_tag); 00068 00069 info.add("X509.Certificate.public_key", 00070 PEM_Code::encode( 00071 ASN1::put_in_sequence(unlock(public_key.value)), 00072 "PUBLIC KEY" 00073 ) 00074 ); 00075 00076 BER_Object attr_bits = cert_req_info.get_next_object(); 00077 00078 if(attr_bits.type_tag == 0 && 00079 attr_bits.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) 00080 { 00081 BER_Decoder attributes(attr_bits.value); 00082 while(attributes.more_items()) 00083 { 00084 Attribute attr; 00085 attributes.decode(attr); 00086 handle_attribute(attr); 00087 } 00088 attributes.verify_end(); 00089 } 00090 else if(attr_bits.type_tag != NO_OBJECT) 00091 throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for attributes", 00092 attr_bits.type_tag, attr_bits.class_tag); 00093 00094 cert_req_info.verify_end(); 00095 00096 if(!this->check_signature(subject_public_key())) 00097 throw Decoding_Error("PKCS #10 request: Bad signature detected"); 00098 } 00099 00100 /* 00101 * Handle attributes in a PKCS #10 request 00102 */ 00103 void PKCS10_Request::handle_attribute(const Attribute& attr) 00104 { 00105 BER_Decoder value(attr.parameters); 00106 00107 if(attr.oid == OIDS::lookup("PKCS9.EmailAddress")) 00108 { 00109 ASN1_String email; 00110 value.decode(email); 00111 info.add("RFC822", email.value()); 00112 } 00113 else if(attr.oid == OIDS::lookup("PKCS9.ChallengePassword")) 00114 { 00115 ASN1_String challenge_password; 00116 value.decode(challenge_password); 00117 info.add("PKCS9.ChallengePassword", challenge_password.value()); 00118 } 00119 else if(attr.oid == OIDS::lookup("PKCS9.ExtensionRequest")) 00120 { 00121 Extensions extensions; 00122 value.decode(extensions).verify_end(); 00123 00124 Data_Store issuer_info; 00125 extensions.contents_to(info, issuer_info); 00126 } 00127 } 00128 00129 /* 00130 * Return the challenge password (if any) 00131 */ 00132 std::string PKCS10_Request::challenge_password() const 00133 { 00134 return info.get1("PKCS9.ChallengePassword"); 00135 } 00136 00137 /* 00138 * Return the name of the requestor 00139 */ 00140 X509_DN PKCS10_Request::subject_dn() const 00141 { 00142 return create_dn(info); 00143 } 00144 00145 /* 00146 * Return the public key of the requestor 00147 */ 00148 std::vector<byte> PKCS10_Request::raw_public_key() const 00149 { 00150 DataSource_Memory source(info.get1("X509.Certificate.public_key")); 00151 return unlock(PEM_Code::decode_check_label(source, "PUBLIC KEY")); 00152 } 00153 00154 /* 00155 * Return the public key of the requestor 00156 */ 00157 Public_Key* PKCS10_Request::subject_public_key() const 00158 { 00159 DataSource_Memory source(info.get1("X509.Certificate.public_key")); 00160 return X509::load_key(source); 00161 } 00162 00163 /* 00164 * Return the alternative names of the requestor 00165 */ 00166 AlternativeName PKCS10_Request::subject_alt_name() const 00167 { 00168 return create_alt_name(info); 00169 } 00170 00171 /* 00172 * Return the key constraints (if any) 00173 */ 00174 Key_Constraints PKCS10_Request::constraints() const 00175 { 00176 return Key_Constraints(info.get1_u32bit("X509v3.KeyUsage", NO_CONSTRAINTS)); 00177 } 00178 00179 /* 00180 * Return the extendend key constraints (if any) 00181 */ 00182 std::vector<OID> PKCS10_Request::ex_constraints() const 00183 { 00184 std::vector<std::string> oids = info.get("X509v3.ExtendedKeyUsage"); 00185 00186 std::vector<OID> result; 00187 for(size_t i = 0; i != oids.size(); ++i) 00188 result.push_back(OID(oids[i])); 00189 return result; 00190 } 00191 00192 /* 00193 * Return is a CA certificate is requested 00194 */ 00195 bool PKCS10_Request::is_CA() const 00196 { 00197 return (info.get1_u32bit("X509v3.BasicConstraints.is_ca") > 0); 00198 } 00199 00200 /* 00201 * Return the desired path limit (if any) 00202 */ 00203 u32bit PKCS10_Request::path_limit() const 00204 { 00205 return info.get1_u32bit("X509v3.BasicConstraints.path_constraint", 0); 00206 } 00207 00208 }