HTTPS Server with full SSL/TLS support

Greetings to all I would like to create a local web server so that I can handle Github webhooks or
Stripe payment confirmation which are being send to only SSL/HTTPS endpoints.

Since the whole web is now fully encrypted I would like to be able via the Socket API and free https://letsencrypt.org/ certificate to have that functionality in my app.

Is there any body here who has that implemented all in AS3?

Best Regards

Let’s clarify first what you try to do …

how Github can connect to your “web server” when this one is “local” ?

Or how Github can differentiate between your localhost and the localhost of someone else ?

Except it is not about sockets, it is about domain names.

Nobody can really validate “localhost” because everybody can own it and host it.

see Let’s Encrypt documentation Certificates for localhost

Sometimes people want to get a certificate for the hostname “localhost”, either for use in local development, or for distribution with a native application that needs to communicate with a web application. Let’s Encrypt can’t provide certificates for “localhost” because nobody uniquely owns it, and it’s not rooted in a top level domain like “.com” or “.net”. It’s possible to set up your own domain name that happens to resolve to 127.0.0.1 , and get a certificate for it using the DNS challenge. However, this is generally a bad idea and there are better options.

see the rest of the doc about “Making and trusting your own certificates”.


Not an AS3 problem.

Otherwise provide more details about what you try to do.

Forget about the details I already have an HTTP Server in AS3.
It is accessible by the outside world via port 80 and my router.

I just need to enable HTTPS on that server the same way as any other platform like nodejs or golang.

Basic pure HTTPS in AS3 server which loads the certificates and do the encryption/decryption.

Ex: my server is http://myservername.dyndns.com

The calls are answered by my HTTP Server running via Socket.

Let’s keep this conversation KISS.

I am aware that as3crypto library has some TLS engine but it was not updated for a long time and it is not really up to date to the new SSL/TLS standard. Is there any other way to come up with a simple server like this : https://gist.github.com/denji/12b3a568f092ab951456

package main

import (
    "crypto/tls"
    "log"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
        w.Write([]byte("This is an example server.\n"))
    })
    cfg := &tls.Config{
        MinVersion:               tls.VersionTLS12,
        CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
        PreferServerCipherSuites: true,
        CipherSuites: []uint16{
            tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
            tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
        },
    }
    srv := &http.Server{
        Addr:         ":443",
        Handler:      mux,
        TLSConfig:    cfg,
        TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
    }
    log.Fatal(srv.ListenAndServeTLS("tls.crt", "tls.key"))
}

No, you have a ServerSocket class that is listening on an IP address and a port.

You can not register certificates on IP addresses, only on domain names.

Because of that you CAN NOT handle the SSL/TLS from there.

Answering to HTTP requests from a socket server is one thing,
being a real HTTP server that can handle SNI and SSL/TLS certificates is something more complicated to say the least, see SSL with Virtual Hosts Using SNI.

You don’t need to implement all the SNI and certificates programming, you just need to understand few basics about servers.

On your FQDN (Fully Qualified Domain Name) eg. myservername.dyndns.com
have an HTTP server, Apache for example, to listen on port 80 and 443

Then simply do a reverse proxy to your socket server listening on port 8080 or whatever.

That way apache deal with the SNI, the SSL/TLS, and your socket server just have to handle HTTP requests and responses.

Something like that

<VirtualHost *:80>

    ServerAdmin email@domain.com
    ServerName myservername.dyndns.com
    ServerSignature Off

    DocumentRoot /var/www/html/htdocs
    
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass /.well-known !
    ProxyPass "/" "http://localhost:8080/"
    ProxyPassReverse "/" "http://localhost:8080/"

    LogLevel error
    ErrorLog ${APACHE_LOG_DIR}/myservername-error.log
    CustomLog ${APACHE_LOG_DIR}/myservername-access.log combined

</VirtualHost>

and then

<VirtualHost *:443>

    ServerAdmin email@domain.com
    ServerName myservername.dyndns.com
    ServerSignature Off

    DocumentRoot /var/www/html/htdocs
    
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass /.well-known !
    ProxyPass "/" "http://localhost:8080/"
    ProxyPassReverse "/" "http://localhost:8080/"

    LogLevel error
    ErrorLog ${APACHE_LOG_DIR}/myservername-error.log
    CustomLog ${APACHE_LOG_DIR}/myservername-access.log combined

    SSLEngine on
    SSLCertificateFile      /etc/letsencrypt/live/myservername.dyndns.com/cert.pem
    SSLCertificateChainFile /etc/letsencrypt/live/myservername.dyndns.com/chain.pem
    SSLCertificateKeyFile   /etc/letsencrypt/live/myservername.dyndns.com/privkey.pem

</VirtualHost>

The way above is exactly how I would do it with a server in node,js, golang, redtamarin too :smiley: etc.

usually you would want to use a frontend HTTP server (apache, nginx) to a backend socket server (node.js, golang, docker, whatever)

so sure you can try to replicate it yourself doing something like that: How to create an https server?

but with Adobe AIR you don’t have a full HTTP server that can handle certificates already written for you, so that would be a long and tenuous road.

Also, this is what I do in production, this server you’re accessing is behind a reverse proxy, which allow me to serve the discourse instance, but also serve pages in ActionScript 3, for example: https://discuss.as3lang.org/printenv.as (side note: this page will only be available 24h for security reasons).

Here the content of printenv.as

#!/usr/bin/as3shebang

import shell.*;

trace( "Content-Type: text/plain; charset=utf-8" );
trace( "" );
trace( "environment variables:" );
trace( Program.environ.join( "\r" ) );

Well I appreciate your solution but I don’t really like patched work outside of my development environment. I don’t want to deal with many other external solutions unless I really have to. Somehow the solution I came up with is to create an ANE which will integrate all the basic HTTP/HTTPS server functionalities with the possibility to add dynamic routing via AS3 to C++ code. That way when I want to intercept any call from outside world via HTTPS here’s how it is going to work.

  1. Air app is loading and at the same time loading the HTTPS ANE server
  2. From AS3 side create a dummy route in ANE for what ever dynamic gituhb(webhook)/stripe(API) call I want to intercept when they contact my server due to an action from their side.
  3. The ANE sends to my internal route manager the body of the call.
  4. Let the responsible class handle the parsing of the data and if necessary via URLoader send a normal HTTPS answer to the target external source.

I don’t like that my solutions get all scattered around I like when everything is independant at the same time well integrate in one box.

I hope my solution will inspire some of you :smiley:

Best regards

so you went from

to

OK good luck

and for

it is only a solution when it is implemented, for now you just have an idea
but do let us when it is implemented

Also to not have wasted too much time on the subject
“hey I want to host my own socket server in AIR and use SSL/TLS”

here some more infos

  • the Apache server above is a valid solution
    mainly learning to install and configure apache

  • another solution if you would prefer to not have a full web server running
    use a forwarding SSL/TLS proxy like stunnel
    also call a TLS termination proxy
    for the case where you doing mainly server socket but not HTTP
    this kind of proxy would take care of the encryption/certificates part at the edge
    and you will just have to focus on your socket protocol in the clear

    • for example, if I wanted to use a socket server with Redtamarin
      which does not support SSL/TLS yet, I would use stunnel for the inbound connection
      eg. socket clients – secure socket --> stunnel --> redtamarin socket server
    • another example, if I wanted to connect to some gmail and other G suite mail server
      from Redtamarin, I could use stunnel for the outbound connection
      see plenty of examples in the Sample stunnel configuration file
      eg. redtamarin email client --> stunnel --> gmail SMTP
  • yet another solution: cloudflare
    you can Manage dynamic IPs in Cloudflare DNS programmatically
    and you can configure End-to-end HTTPS with Cloudflare
    more exactly

    The Flexible SSL option allows a secure HTTPS connection between your visitor and Cloudflare, but forces Cloudflare to connect to your origin web server over unencrypted HTTP. An SSL certificate is not required on your origin web server and your visitors will still see the site as being HTTPS enabled.

    Here cloudflare act as a kind of stunnel in the cloud


There are some battle in programming that are best to leave for later and to certainly not underestimate, a good HTTP server is not small potato to implement, and a HTTP server that deal with SSL/TLS is something even harder, that said it is possible with time and dedication.

Now if you end up implementing such a thing you will need the following tools

because TLS Security 6: Examples of TLS Vulnerabilities and Attacks
(reading the other chapters 1 to 5 is also a good start)

“HTTPS” is not just a label you stamp on a server the S stand for secure

even with already existing servers and libraries decades old it is very easy to misconfigure things and be vulnerable to many SSL/TLS exploits out there, so implementing it … not something someone improvise on a whim on a sunday :smiley:

The main question was this : is this possible in AS3

package main

import (
    "crypto/tls"
    "log"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
        w.Write([]byte("This is an example server.\n"))
    })
    cfg := &tls.Config{
        MinVersion:               tls.VersionTLS12,
        CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
        PreferServerCipherSuites: true,
        CipherSuites: []uint16{
            tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
            tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
        },
    }
    srv := &http.Server{
        Addr:         ":443",
        Handler:      mux,
        TLSConfig:    cfg,
        TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
    }
    log.Fatal(srv.ListenAndServeTLS("tls.crt", "tls.key"))
}

The simple answer had to be “In insecure mode without TLS/SSL it is possible, but not otherwise” and not so complicated thread.

you started this thread
don’t tell me what I can and can not say or how to say it

I am not saying to you what to do I just tried to underline the fact that you took something simple and made a big story out of a simple question while I gave even a code example which was pretty much the question meaning.

You took the solution out of AS3 and started to go in uncharted territories which is ok if you want but I like to stay straight to the core of the context.

Just start from this thread again and you will realize that you went off topic.

What I am trying to say is stop projecting yourself into the thread and learn to pin point the meat of the subject matter.

Thank you for your contribution :slight_smile:

ok you want to go into the meat of the details… fine

what was the point of asking the question in the first place?

I asked you to provide details, remember?

but nooooo you could not do that, right?

what you see as “uncharted territories” is maybe because from the very first message you were already assuming a direction toward some solution

what you consider “off topic” is your limitation to see a forum thread as only for you,
when in fact it is for everyone, and oh bugger someone brought solutions outside of your assumptions

and honestly I didn’t go deep into the details

I could have asked:

why are you building an HTTP server with AIR in the first place?

what can you do with AIR that can not be done with any other backend language that are already working server-side?

even better, what can you do in AS3 with AIR that can not be done with Redtamarin which is made to work on the server-side?

why hosting on your local machine is so important? is it because it is cheap? it is because you don’t know servers?

hey guess what?, you did not give any details about why you wanted to do it like that, or what you were trying to achieve, and now you came back with “hu ho that’s off topic”

what’s off topic exactly?

does it hurt to have a bit of knowledge about reverse proxy? or cloudflare? or stunnel? or servers in general?

even if you don’t want to do it like that, does it hurt that others could see those different paths to solve a similar problem?

assumptions … they can be false, more often than few
and people don’t know what they don’t know

you talk about simple?, well … please do start working on your ANE and come back later, maybe in a few weeks?, and tell us all how it was much simpler to write that HTTP server in C++ instead of setting up some of the solutions mentioned above, you know the one you’re assuming are “not simple”.

I will even set you on the easier path, look at nodejs/http-parser, same HTTP server as used by node.js, now you just need to upgrade it so it can work with a lib like openSSL, oh and because you do an ANE then you’ll have to run that server on its own thread and dispatch events from the C/C++ side to the AS3 side … but yeah all that is real simple.

I got another idea I can from simple Java HTTPS server implementation compile directly to AS3 and use the SSLEngine of Java in my code to decode the requests received from an AS3 Socket server.

You see sometime it is worth to stay inside of thread context so that the snake ends up biting its tail.

You are still pushing solutions outside of AS3 when I still want to only stay as close as possible to AS3.

Now maybe this solution is worth exploring instead of going in nodeJS/Apache/Mozilla/Cloudflare/etc…

I realized working in IT, IT people in general (still there are few exceptions) are linear minded and are lacking the capacity of thinking outside of the box because the only way their brain is working is in term of IF … THEN … ELSE. It is good to be logical but logic is not solving all problems.

you’re underestimating this task by a long long shot

you still don’t say why, escaping all the questions asked above

personally I’m done, I just asked those questions because you insisted going into the meat of things with your “off topic” and “uncharted territories”

my personal conclusion is you are taking on a task way above your head,
so good luck

don’t hesitate to revive this thread when you got some real code going and working