# include  "selfdrive/ui/qt/api.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <openssl/pem.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <openssl/rsa.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QApplication> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QCryptographicHash> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <QDateTime> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <QDebug> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <QJsonDocument> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <QNetworkRequest> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <memory> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <string> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "common/util.h" 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "system/hardware/hw.h" 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "selfdrive/ui/qt/util.h" 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  CommaApi  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								RSA  * get_rsa_private_key ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  static  std : : unique_ptr < RSA ,  decltype ( & RSA_free ) >  rsa_private ( nullptr ,  RSA_free ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! rsa_private )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FILE  * fp  =  fopen ( Path : : rsa_file ( ) . c_str ( ) ,  " rb " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! fp )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      qDebug ( )  < <  " No RSA private key found, please run manager.py or registration.py " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  nullptr ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rsa_private . reset ( PEM_read_RSAPrivateKey ( fp ,  NULL ,  NULL ,  NULL ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fclose ( fp ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  rsa_private . get ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								QByteArray  rsa_sign ( const  QByteArray  & data )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSA  * rsa_private  =  get_rsa_private_key ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! rsa_private )  return  { } ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QByteArray  sig ( RSA_size ( rsa_private ) ,  Qt : : Uninitialized ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  int  sig_len ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  ret  =  RSA_sign ( NID_sha256 ,  ( unsigned  char * ) data . data ( ) ,  data . size ( ) ,  ( unsigned  char * ) sig . data ( ) ,  & sig_len ,  rsa_private ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  assert ( ret  = =  1 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  assert ( sig . size ( )  = =  sig_len ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  sig ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								QString  create_jwt ( const  QJsonObject  & payloads ,  int  expiry )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QJsonObject  header  =  { { " alg " ,  " RS256 " } } ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  t  =  QDateTime : : currentSecsSinceEpoch ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QJsonObject  payload  =  { { " identity " ,  getDongleId ( ) . value_or ( " " ) } ,  { " nbf " ,  t } ,  { " iat " ,  t } ,  { " exp " ,  t  +  expiry } } ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  ( auto  it  =  payloads . begin ( ) ;  it  ! =  payloads . end ( ) ;  + + it )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    payload . insert ( it . key ( ) ,  it . value ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  auto  b64_opts  =  QByteArray : : Base64UrlEncoding  |  QByteArray : : OmitTrailingEquals ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QString  jwt  =  QJsonDocument ( header ) . toJson ( QJsonDocument : : Compact ) . toBase64 ( b64_opts )  +  ' . '  + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                QJsonDocument ( payload ) . toJson ( QJsonDocument : : Compact ) . toBase64 ( b64_opts ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  hash  =  QCryptographicHash : : hash ( jwt . toUtf8 ( ) ,  QCryptographicHash : : Sha256 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  jwt  +  " . "  +  rsa_sign ( hash ) . toBase64 ( b64_opts ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								}   // namespace CommaApi
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								HttpRequest : : HttpRequest ( QObject  * parent ,  bool  create_jwt ,  int  timeout )  :  create_jwt ( create_jwt ) ,  QObject ( parent )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  networkTimer  =  new  QTimer ( this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  networkTimer - > setSingleShot ( true ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  networkTimer - > setInterval ( timeout ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  connect ( networkTimer ,  & QTimer : : timeout ,  this ,  & HttpRequest : : requestTimeout ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  HttpRequest : : active ( )  const  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  reply  ! =  nullptr ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  HttpRequest : : timeout ( )  const  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  reply  & &  reply - > error ( )  = =  QNetworkReply : : OperationCanceledError ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  HttpRequest : : sendRequest ( const  QString  & requestURL ,  const  HttpRequest : : Method  method )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( active ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    qDebug ( )  < <  " HttpRequest is active " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QString  token ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( create_jwt )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    token  =  CommaApi : : create_jwt ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }  else  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QString  token_json  =  QString : : fromStdString ( util : : read_file ( util : : getenv ( " HOME " )  +  " /.comma/auth.json " ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QJsonDocument  json_d  =  QJsonDocument : : fromJson ( token_json . toUtf8 ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    token  =  json_d [ " access_token " ] . toString ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QNetworkRequest  request ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  request . setUrl ( QUrl ( requestURL ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  request . setRawHeader ( " User-Agent " ,  getUserAgent ( ) . toUtf8 ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! token . isEmpty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    request . setRawHeader ( QByteArray ( " Authorization " ) ,  ( " JWT  "  +  token ) . toUtf8 ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( method  = =  HttpRequest : : Method : : GET )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    reply  =  nam ( ) - > get ( request ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  }  else  if  ( method  = =  HttpRequest : : Method : : DELETE )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    reply  =  nam ( ) - > deleteResource ( request ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  networkTimer - > start ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  connect ( reply ,  & QNetworkReply : : finished ,  this ,  & HttpRequest : : requestFinished ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  HttpRequest : : requestTimeout ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  reply - > abort ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  HttpRequest : : requestFinished ( )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  networkTimer - > stop ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( reply - > error ( )  = =  QNetworkReply : : NoError )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    emit  requestDone ( reply - > readAll ( ) ,  true ,  reply - > error ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  }  else  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QString  error ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( reply - > error ( )  = =  QNetworkReply : : OperationCanceledError )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      nam ( ) - > clearAccessCache ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nam ( ) - > clearConnectionCache ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      error  =  " Request timed out " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      error  =  reply - > errorString ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    emit  requestDone ( error ,  false ,  reply - > error ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  reply - > deleteLater ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  reply  =  nullptr ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								QNetworkAccessManager  * HttpRequest : : nam ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  static  QNetworkAccessManager  * networkAccessManager  =  new  QNetworkAccessManager ( qApp ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  networkAccessManager ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}