Edzelf / Esp-radio

Internet radio based on Esp8266 and VS1053.
MIT License
628 stars 199 forks source link

https ssl Streams #185

Open marrog86 opened 4 years ago

marrog86 commented 4 years ago

Hello,

It seems that this porgram not works wis https Streams.

So i tried to implement: but it does not work

bool connecttohost()
{

  int         inx ;                                 // Position of ":" in hostname
  char*       pfs ;                                 // Pointer to formatted string
  int         port = -1 ;                           // Port number for host
  String      extension = "/" ;                     // May be like "/mp3" in "skonto.ls.lv:8002/mp3"
  String      hostwoext ;                           // Host without extension and portnumber
  String      prot = "http";
  String      partstring; 
   WiFiClientSecure* secClient;

  stop_mp3client() ;                                // Disconnect if still connected
  dbgprint ( "Connect to new host '%s'", host.c_str() ) ;
  displayinfo ( "   ** Internet radio **", 0, 20, WHITE ) ;
  datamode = INIT ;                                 // Start default in metamode
  chunked = false ;                                 // Assume not chunked
  if ( host.endsWith ( ".m3u" ) )                   // Is it an m3u playlist?
  {
    playlist = host ;                               // Save copy of playlist URL
    datamode = PLAYLISTINIT ;                       // Yes, start in PLAYLIST mode
    if ( playlist_num == 0 )                        // First entry to play?
    {
      playlist_num = 1 ;                            // Yes, set index
    }
    dbgprint ( "Playlist request, entry %d", playlist_num ) ;
  }
  // In the URL there may be an extension
  partstring = host; 
  inx = partstring.indexOf ( "//" ) ;                      // Search for end of protocoll
   if ( inx > 0 )                                    // Is there an extension?
  {
    partstring = host.substring ( inx+2 ) ;            // Yes, change the default
    prot = host.substring ( 0, inx-1 ) ;         // Host without extension
    prot.toUpperCase();
  }

  inx = partstring.indexOf ( "/" ) ;                      // Search for begin of extension
  if ( inx > 0 )                                    // Is there an extension?
  {
    extension = partstring.substring ( inx ) ;            // Yes, change the default
    hostwoext = partstring.substring ( 0, inx ) ;         // Host without extension
  }
  // In the URL there may be a portnumber
  inx = partstring.indexOf ( ":" ) ;                      // Search for separator
  if ( inx >= 0 )                                   // Portnumber available?
  {
    port = partstring.substring ( inx + 1 ).toInt() ;     // Get portnumber as integer
    hostwoext = partstring.substring ( 0, inx ) ;         // Host without portnumber
  }

  if(prot.equals("HTTPS"))
  {
    if(port == -1)
      port = 443;

    secClient = new WiFiClientSecure() ;
    secClient->setInsecure();
    mp3client = secClient;
  }
  else{
     if(port == -1)
      port = 80;
    mp3client = new WiFiClient() ;
  }

  pfs = dbgprint ( "Connect to %s on port %d, extension %s , protokol %s",
                   hostwoext.c_str(), port, extension.c_str() ,prot.c_str()) ;
  displayinfo ( pfs, 60, 66, YELLOW ) ;             // Show info at position 60..125

  for(int retry=0;retry<1;retry++)
  {
    dbgprint ( "Request %i try", retry) ;
    if ( mp3client->connect ( hostwoext.c_str(), port ) )
    {
      dbgprint ( "Connected to server" ) ;
      // This will send the request to the server. Request metadata.
      mp3client->print ( String ( "GET " ) +
                         extension +
                        String ( " HTTP/1.1\r\n" ) +
                        String ( "Host: " ) +
                        hostwoext +
                        String ( "\r\n" ) +
                        String ( "Icy-MetaData:1\r\n" ) +
                        String ( "Connection: close\r\n\r\n" ) ) ;
      return true ;
    }
    //delay(2000);
  }
  dbgprint ( "Request '%s' failed!", host.c_str() ) ;
  if(prot.equals("HTTPS"))
  {
    dbgprint ("%i", secClient->getLastSSLError() );
  }
  return false ;
}

error code is -1000 pleas help, i am new in this programming language.

Edzelf commented 4 years ago

What's the point of sending public streams over SSL?

marrog86 commented 4 years ago

Some radio stations only offers ONLY https connections, for example: https://arabellarelax.stream.arabella.at/heroldrelax

I am out of ideas, what the failure could bee. I have an successfull example code for ssl connections.

In an other intent, i changed all your WifiClient objects and datatypes to an WifiClientSecured. The only function i added was isInsecure(), all other lines are equal to your code. But that also not working.

koskee commented 4 years ago

I had brought this up before and we never did end up solving it, as far as I know anyway. In general, SSL would require you to have valid public/private keys available (which look like big blocks of randomized text) which are then used to apply the encryption algorithms. Not sure how much of this is true for audio streams but it is likely similar. Also I haven't done a whole lot of experimenting with the wifisecure library, so I'm not sure as to the level of abstraction it has. It may be that it handles most of the encryption/decryption logic behind the scenes, but i'm fairly certain you would at least have to provide the above mentioned keys somehow, as they are supposed to be unique to the user afaik.

Ed, the Internet in general is moving towards using ssl for everything.. for security reasons mostly. There are several advocacy groups that are promoting "ssl by default" as a concept so it seems likely that this will only grow as an issue in the future, as more and more sites begin to implement this. The only reason I can think of for why a station might choose to do it this way is possibly because of copyright reasons.. By that I mean that most radio stations are under obligation to pay royalties for the music they play and this would help prevent interception and/or help them to track how many "real" authenticated users are listening to the station and would also probably make it easier to enforce geo-location type censorship (which might also limit the royalties that would be payable?) but that's just a thought. I'm not certain about that, but it seems like a possibility to me anyway. It's unfortunate because it limits access to those streams to more powerful hardware than would be necessary otherwise (altho I don't see any obvious reason that the ESP32 couldn't handle it, but it would obviously leave less CPU cycles available for anything else in the end)

Found this: https://blog.brlogic.com/en/ssl-certificate-and-its-benefits-for-your-online-radio-station/

Derek-K commented 2 years ago

@marrog86 Hey, I like your mod, I looked at your code, and it seems alright to me. My gut feeling could be a memory issue. I don't have a chance to try yet, but what if you try to reduce the ring buffer size for streaming and see if it at least connect.

I am not sure when I get a chance to try your mod, hopefully soon. Because I just run into a radio station only stream over SSL as well and to make it worst, I have added a touchscreen and a bigger LCD using the TFT_eSPI library. So I am even tighter on memory...

Please keep us posted if you do have any updates.

  if(prot.equals("HTTPS"))
  {
    if(port == -1)
      port = 443;

    secClient = new WiFiClientSecure() ;
    secClient->setInsecure();
    mp3client = secClient;
  }
  else{
     if(port == -1)
      port = 80;
    mp3client = new WiFiClient() ;
  }