removed TODO reminder
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_cert.c
index 81a2b33..b8df5ad 100644 (file)
@@ -1199,6 +1199,8 @@ struct private_builder_t {
        certificate_t *sign_cert;
        /** private key to sign, if we generate a new cert */
        private_key_t *sign_key;
+       /** digest algorithm to be used for signature */
+       hash_algorithm_t digest_alg;
 };
 
 /**
@@ -1208,7 +1210,7 @@ static bool generate(private_builder_t *this)
 {
        chunk_t extensions = chunk_empty;
        identification_t *issuer, *subject;
-       chunk_t key_info, key;
+       chunk_t key_info;
        signature_scheme_t scheme;
        hasher_t *hasher;
        
@@ -1236,7 +1238,7 @@ static bool generate(private_builder_t *this)
                this->cert->notBefore = time(NULL);
        }
        if (!this->cert->notAfter)
-       {       /* defaults to 1 years from now on */
+       {       /* defaults to 1 year from now */
                this->cert->notAfter = this->cert->notBefore + 60 * 60 * 24 * 365;
        }
        this->cert->flags = this->flags;
@@ -1244,35 +1246,65 @@ static bool generate(private_builder_t *this)
        switch (this->sign_key->get_type(this->sign_key))
        {
                case KEY_RSA:
-                       this->cert->algorithm = OID_SHA1_WITH_RSA;
-                       scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+                       switch (this->digest_alg)
+                       {
+                               case HASH_MD5:
+                                       this->cert->algorithm = OID_MD5_WITH_RSA;
+                                       break;
+                               case HASH_SHA1:
+                                       this->cert->algorithm = OID_SHA1_WITH_RSA;
+                                       break;
+                               case HASH_SHA224:
+                                       this->cert->algorithm = OID_SHA224_WITH_RSA;
+                                       break;
+                               case HASH_SHA256:
+                                       this->cert->algorithm = OID_SHA256_WITH_RSA;
+                                       break;
+                               case HASH_SHA384:
+                                       this->cert->algorithm = OID_SHA384_WITH_RSA;
+                                       break;
+                               case HASH_SHA512:
+                                       this->cert->algorithm = OID_SHA512_WITH_RSA;
+                                       break;
+                               default:
+                                       return FALSE;
+                       }
                        break;
-               default:
-                       return FALSE;
-       }
-       
-       switch (this->cert->public_key->get_type(this->cert->public_key))
-       {
-               case KEY_RSA:
-                       if (!this->cert->public_key->get_encoding(this->cert->public_key,
-                                                                                                         KEY_PUB_ASN1_DER, &key))
+               case KEY_ECDSA:
+                       switch (this->digest_alg)
                        {
-                               return FALSE;
+                               case HASH_SHA1:
+                                       this->cert->algorithm = OID_ECDSA_WITH_SHA1;
+                                       break;
+                               case HASH_SHA256:
+                                       this->cert->algorithm = OID_ECDSA_WITH_SHA256;
+                                       break;
+                               case HASH_SHA384:
+                                       this->cert->algorithm = OID_ECDSA_WITH_SHA384;
+                                       break;
+                               case HASH_SHA512:
+                                       this->cert->algorithm = OID_ECDSA_WITH_SHA512;
+                                       break;
+                               default:
+                                       return FALSE;
                        }
-                       key_info = asn1_wrap(ASN1_SEQUENCE, "cm",
-                                                       asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
-                                                       asn1_bitstring("m", key));
                        break;
                default:
                        return FALSE;
        }
-       
+       scheme = signature_scheme_from_oid(this->cert->algorithm);
+
+       if (!this->cert->public_key->get_encoding(this->cert->public_key,
+                                                                                         KEY_PUB_SPKI_ASN1_DER, &key_info))
+       {
+               return FALSE;
+       }
        if (this->cert->subjectAltNames->get_count(this->cert->subjectAltNames))
        {
                /* TODO: encode subjectAltNames */
        }
        
-       this->cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm", 
+       this->cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm", 
                asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
                asn1_integer("c", this->cert->serialNumber),
                asn1_algorithmIdentifier(this->cert->algorithm),
@@ -1288,7 +1320,7 @@ static bool generate(private_builder_t *this)
        {
                return FALSE;
        }
-       this->cert->encoding = asn1_wrap(ASN1_SEQUENCE, "ccm",
+       this->cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
                                                                this->cert->tbsCertificate,
                                                                asn1_algorithmIdentifier(this->cert->algorithm),
                                                                asn1_bitstring("c", this->cert->signature));
@@ -1402,6 +1434,9 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        this->cert->serialNumber = chunk_clone(serial);
                        break;
                }
+               case BUILD_DIGEST_ALG:
+                       this->digest_alg = va_arg(args, int);
+                       break;
                default:
                        /* abort if unsupported option */
                        if (this->cert)
@@ -1432,6 +1467,7 @@ builder_t *x509_cert_builder(certificate_type_t type)
        this->flags = 0;
        this->sign_cert = NULL;
        this->sign_key = NULL;
+       this->digest_alg = HASH_SHA1;
        this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
        this->public.build = (void*(*)(builder_t *this))build;