Repository: localstack/localstack

Issue:
Can't get custom SSL certificate to work
# Type of request: This is a ...
[X] bug report
[ ] feature request

# Detailed description
I try to configure SSL to work with a certificate bundle from my CA.
Here's an excerpt from my `docker-compose.yml` 


```
  localstack:
    image: localstack/localstack
    ports:
      - 4566:4566
      - "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"
    environment:
      - LOCALSTACK_SERVICES=s3,secretsmanager
      - LOCALSTACK_DEFAULT_REGION=us-east-1
      - LOCALSTACK_USE_SSL=true
      - LOCALSTACK_DATA_DIR=/tmp/localstack/data
      - LOCALSTACK_PORT_WEB_UI=8080
      - LOCALSTACK_HOSTNAME=aws.local.domain.com
    volumes:
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
      - ./support/docker/localstack/aws.local.domain.com.pem:/tmp/localstack/server.test.pem
      - ./support/docker/localstack/aws.local.domain.com.crt:/tmp/localstack/server.test.pem.crt
      - ./support/docker/localstack/aws.local.domain.com.key:/tmp/localstack/server.test.pem.key
```

My `.pem` file has the following format:


```
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
```

Here's what I see in `localstack` container logs when I run `docker-compose up`:


```
localstack | Waiting for all LocalStack services to be ready
localstack | Starting edge router (https port 4566)...
localstack | Starting mock S3 service in https ports 4566 (recommended) and 4572 (deprecated)...
localstack | 2020-05-31T16:22:20:INFO:localstack.utils.common: Unable to store key/cert files for custom SSL certificate: substring not found
localstack | 2020-05-31T16:22:20:INFO:localstack.multiserver: Starting multi API server process on port 34651
localstack | 2020-05-31T16:22:20:INFO:localstack.utils.common: Unable to store key/cert files for custom SSL certificate: substring not found
localstack | Starting mock Secrets Manager service in https ports 4566 (recommended) and 4584 (deprecated)...
localstack | 2020-05-31T16:22:21:INFO:localstack.utils.common: Unable to store key/cert files for custom SSL certificate: substring not found
localstack | Waiting for all LocalStack services to be ready
localstack | Ready.
```

I also have `aws.local.domain.com` in my `/etc/hosts` file pointing to `127.0.0.1`

...

## Expected behavior
I should be able to issue AWS CLI commands successfully. 
...

## Actual behavior
Here's the output from AWS CLI:


```
$ aws --endpoint-url=https://aws.local.domain.com:4566 s3 ls

SSL validation failed for https://aws.local.domain.com:4566/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)
```

...

Is there anything I'm missing?



┆Issue is synchronized with this [Jira Bug](https://localstack.atlassian.net/browse/LOC-192) by [Unito](https://www.unito.io/learn-more)



Discussion:
Thanks for reporting @b0ric. Can you please double-check whether LocalStack actually picks up your custom certificate. For example, does the following print the subject name of your custom certificate?
```
openssl s_client -showcerts -connect aws.local.domain.com:4566 | grep subject
```
Also, I'm not too familiar with overlapping volume mounts in docker-compose, but you could also try configuring only the following volume, and then placing the certs directly into your local $TMPDIR (instead of adding the three additional mounts):
```
    volumes:
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
```
Hope that helps - please keep us posted with the details. Thanks

Resolving patch:
diff --git a/localstack/utils/common.py b/localstack/utils/common.py
--- a/localstack/utils/common.py
+++ b/localstack/utils/common.py
@@ -1208,13 +1208,19 @@ def all_exist(*files):
     def store_cert_key_files(base_filename):
         key_file_name = '%s.key' % base_filename
         cert_file_name = '%s.crt' % base_filename
+        # TODO: Cleaner code to load the cert dinamically
         # extract key and cert from target_file and store into separate files
         content = load_file(target_file)
         key_start = '-----BEGIN PRIVATE KEY-----'
         key_end = '-----END PRIVATE KEY-----'
+        rsa_key_start = '-----BEGIN RSA PRIVATE KEY-----'
+        rsa_key_end = '-----END RSA PRIVATE KEY-----'
         cert_start = '-----BEGIN CERTIFICATE-----'
         cert_end = '-----END CERTIFICATE-----'
-        key_content = content[content.index(key_start): content.index(key_end) + len(key_end)]
+        if rsa_key_start in content:
+            key_content = content[content.index(rsa_key_start): content.index(rsa_key_end) + len(rsa_key_end)]
+        else:
+            key_content = content[content.index(key_start): content.index(key_end) + len(key_end)]
         cert_content = content[content.index(cert_start): content.rindex(cert_end) + len(cert_end)]
         save_file(key_file_name, key_content)
         save_file(cert_file_name, cert_content)


Test patch: