Botan  1.11.15
src/lib/cert/x509/pkcs10.cpp
Go to the documentation of this file.
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 }