我需要在服务器/客户端中使用X509运行GnuTLS(有疑问,需要修复)

时间:2018-12-26 00:24:15

标签: ssl networking openssl gnutls

如我在以下网站中提到的示例中所见,关于我以前使用的代码版本与以前几乎相同的示例,GnuTLS发生了巨大变化:

问题在于,在必须为客户端程序使用授权证书之前,现在需要仅在服务器端使用的证书和密钥。这是什么重大变化?最后,在生成的证书中,哪一方属于私人和公共部门? (根据示例,我必须将gnutls_certificate_set_x509_trust_file替换为gnutls_certificate_set_x509_key_file

在此“服务器和客户端”示例中,必须使用openssl命令的参数来生成所有必需证书的几行?

生成的证书的文件名问题也非常令人困惑,有时是.pem有时是.crt / .key,告诉您我应该如何准确创建这些名称(如果您认为其中一些错误的话) )。

由于GnuTLS的更新,它已停止工作,现在握手失败,从而导致服务器握手失败,并且客户端中的用户继续认为连接良好。

这是代码:

服务器:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <gnutls/gnutls.h>

int main(){
  const char*txterr;
  int lsck;
  gnutls_certificate_credentials_t xcred;
  gnutls_priority_t pcache;
  gnutls_session_t sesion;
  sockaddr_in _cli;

  //INICIO GLOBAL
  //if(!gnutls_check_version("3.6.15"))return -1;
  if(!gnutls_check_version("3.5.10"))return -1;
  if(gnutls_global_init()<0)return -2;
  if(gnutls_certificate_allocate_credentials(&xcred)<0)return -3;
  if(gnutls_certificate_set_x509_trust_file(xcred,"cert/ca.crt",GNUTLS_X509_FMT_PEM)<0)return -4;
  //if(gnutls_certificate_set_x509_crl_file(xcred,"cert/revocar.crl",GNUTLS_X509_FMT_PEM)<0)return -5;
  if(gnutls_certificate_set_x509_key_file(
    xcred,"cert/serv.crt","cert/serv.key",GNUTLS_X509_FMT_PEM)<0)return -6;
  //if(gnutls_certificate_set_ocsp_status_request_file(xcred,"reqocsp.der",0)<0)return -4;
  if(gnutls_priority_init(&pcache,"PERFORMANCE:%SERVER_PRECEDENCE",&txterr)<0){printf("TLS: %s\n",txterr);return -7;}
  if(gnutls_certificate_set_known_dh_params(xcred,GNUTLS_SEC_PARAM_MEDIUM)<0)return -8;

  //ABRE PUERTO SERVIDOR
  lsck=socket(AF_INET,SOCK_STREAM,0);
  if(lsck==-1){lsck=0;printf("Imposible usar Puerto\n");return -1;}
  {int optval=1;setsockopt(lsck,SOL_SOCKET,SO_REUSEADDR,(void*)&optval,sizeof(int));}
  //Convierte el puerto en Escucha
  {
    struct sockaddr_in dsrv;
    dsrv.sin_family=AF_INET;
    dsrv.sin_port=htons(9080);
    dsrv.sin_addr.s_addr=INADDR_ANY;
    if(bind(lsck,(struct sockaddr*)&dsrv,sizeof(dsrv))!=0)
      {printf("Imposible bindear Puerto\n");return -2;}
    if(listen(lsck,10)!=0)
      {printf("Imposible abrir Puerto\n");return -3;}
  }
  printf("Abriendo Puerto\n");

  //ESCUCHA PUERTO
  if(gnutls_init(&sesion,GNUTLS_SERVER)<0)return -6;
  if(gnutls_priority_set(sesion,pcache)<0)return -6;
  if(gnutls_credentials_set(sesion,GNUTLS_CRD_CERTIFICATE,xcred)<0)return -6;
  gnutls_certificate_server_set_request(sesion,GNUTLS_CERT_IGNORE);
  gnutls_handshake_set_timeout(sesion,GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
  int _scli=sizeof(sockaddr_in);
  int nsck=accept(lsck,(sockaddr*)&_cli,(socklen_t*)&_scli);
  if(nsck<0)return -3;
  gnutls_transport_set_int(sesion,nsck);
  int tm;
  do{
    tm=gnutls_handshake(sesion);
  }while(tm<0&&gnutls_error_is_fatal(tm)==0);
  if(tm<0){close(nsck);gnutls_deinit(sesion);return -6;}
  printf("Entrando Usuario: %x:%d\n",_cli.sin_addr,_cli.sin_port);

  //CIFRA PUERTO CLIENTE
  gnutls_datum_t out;
  gnutls_session_t tls_sesion;
  if(gnutls_init(&tls_sesion,GNUTLS_CLIENT)<0)return -6;
  if(gnutls_server_name_set(tls_sesion,GNUTLS_NAME_DNS,"blackrook.ddns.net",strlen("blackrook.ddns.net"))<0)return -7;
  if(gnutls_set_default_priority(tls_sesion)<0)return -8;
  int ret=gnutls_priority_set_direct(tls_sesion,"NORMAL",&txterr);
  if(ret<0){
    switch(ret){
    case GNUTLS_E_INVALID_REQUEST:
      printf("Error tipo %s\n",txterr);
      return -9;
    }
  }
  if(gnutls_credentials_set(tls_sesion,GNUTLS_CRD_CERTIFICATE,xcred)<0)return -10;
  gnutls_session_set_verify_cert(tls_sesion,"blackrook.ddns.net",0);
  //Toma el FD Socket
  gnutls_transport_set_int(tls_sesion,nsck);
  gnutls_handshake_set_timeout(tls_sesion,GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
  do{ret=gnutls_handshake(tls_sesion);
  }while(ret<0&&!gnutls_error_is_fatal(ret));
  if(ret<0){
    gnutls_certificate_type_t type;
    int status;
    switch(ret){
    case GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR:
      type=gnutls_certificate_type_get(tls_sesion);
      status=gnutls_session_get_verify_cert_status(tls_sesion);
      if(gnutls_certificate_verification_status_print(status,type,&out,0)<0)return -255;
      printf("TLS: cert verify output: %s\n",out.data);
      gnutls_free(out.data);
    }
    printf("TLS: Handshake fallado: %s\n",gnutls_strerror(ret));
    return -11;
  }{
    char*desc=gnutls_session_get_desc(tls_sesion);
    printf("TLS: Session info: %s\n",desc);
    gnutls_free(desc);
  }
  //Envia mensaje cifrado
  char*msg="Este es canal abierto.";
  gnutls_record_send(tls_sesion,msg,strlen(msg)+1);

  //CIERRA
  if(gnutls_bye(tls_sesion,GNUTLS_SHUT_WR)<0)printf("TLS: Falla cerrando\n");
  close(nsck);
  gnutls_deinit(tls_sesion);
  close(lsck);
  gnutls_certificate_free_credentials(xcred);
  gnutls_priority_deinit(pcache);
  gnutls_global_deinit();

  return 0;
}

客户:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <gnutls/gnutls.h>

int main(){
  int fd;
  const char*txterr;
  gnutls_certificate_credentials_t xcred;
  gnutls_session_t tls_sesion;

  //INICIA TLS
  if(!gnutls_check_version("3.5.10"))return -1;
  if(gnutls_global_init()<0)return -2;
  if(gnutls_certificate_allocate_credentials(&xcred)<0)return -3;
  if(gnutls_certificate_set_x509_system_trust(xcred)<0)return -4;
  if(gnutls_certificate_set_x509_trust_file(xcred,"cert/ca.crt",GNUTLS_X509_FMT_PEM)<0)return -5;
  //if(gnutls_certificate_set_x509_key_file(xcred,"cert/cert.pem","cert/key.pem",GNUTLS_X509_FMT_PEM)<0)return -5;

  //ABRE SOCKET
  fd=socket(AF_INET,SOCK_STREAM,0);
  if(fd==-1){printf("Imposible abrir nuevo E/S\n");return -1;}
  struct addrinfo hints,*serv,*p;
  char*zip="blackrook.ddns.net",*zprt="9080";
  memset(&hints,0,sizeof(hints));
  hints.ai_family=AF_UNSPEC;
  hints.ai_socktype=SOCK_STREAM;
  int i,ip;
  if(i=getaddrinfo(zip,zprt,&hints,&serv)){
    printf("Conexion no establecida\n");return 0;}
  for(p=serv;p!=0;p=p->ai_next){
    if(p->ai_addr->sa_family==AF_INET){
      ip=((struct sockaddr_in*)p->ai_addr)->sin_addr.s_addr;
      if(connect(fd,p->ai_addr,p->ai_addrlen)==-1)continue;
      freeaddrinfo(serv);
      printf("Conexion establecida\n");goto JmpConti;
    }
  }freeaddrinfo(serv);printf("Conexion no establecida2\n");return 0;
JmpConti:

  //CIFRA PUERTO
  gnutls_datum_t out;
  if(gnutls_init(&tls_sesion,GNUTLS_CLIENT)<0)return -6;
  if(gnutls_server_name_set(tls_sesion,GNUTLS_NAME_DNS,"blackrook.ddns.net",strlen("blackrook.ddns.net"))<0)return -7;
  if(gnutls_set_default_priority(tls_sesion)<0)return -8;
  int ret=gnutls_priority_set_direct(tls_sesion,"NORMAL",&txterr);
  if(ret<0){
    switch(ret){
    case GNUTLS_E_INVALID_REQUEST:
      printf("Error tipo %s\n",txterr);
      return -9;
    }
  }
  if(gnutls_credentials_set(tls_sesion,GNUTLS_CRD_CERTIFICATE,xcred)<0)return -10;
  gnutls_session_set_verify_cert(tls_sesion,"blackrook.ddns.net",0);
  //Toma el FD Socket
  gnutls_transport_set_int(tls_sesion,fd);
  gnutls_handshake_set_timeout(tls_sesion,GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
  do{ret=gnutls_handshake(tls_sesion);
  }while(ret<0&&!gnutls_error_is_fatal(ret));
  if(ret<0){
    printf("RET:%d\n",ret);
    gnutls_certificate_type_t type;
    int status;
    switch(ret){
    case GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR:
      type=gnutls_certificate_type_get(tls_sesion);
      status=gnutls_session_get_verify_cert_status(tls_sesion);
      if(gnutls_certificate_verification_status_print(status,type,&out,0)<0)return -255;
      printf("TLS: cert verify output: %s\n",out.data);
      gnutls_free(out.data);
    }
    printf("TLS: Handshake fallado: %s\n",gnutls_strerror(ret));
    return -11;
  }{
    char*desc=gnutls_session_get_desc(tls_sesion);
    printf("TLS: Session info: %s\n",desc);
    gnutls_free(desc);
  }
  //Recibe mensaje
  char msg[16387];long max=16387,nres;
  sleep(4);
  nres=gnutls_record_recv(tls_sesion,msg,max);
  printf("R:%s\n",msg);

  //CIERRA PUERTO
  if(gnutls_bye(tls_sesion,GNUTLS_SHUT_RDWR)<0)printf("TLS: Falla cerrando\n");
  close(fd);
  gnutls_deinit(tls_sesion);
  gnutls_certificate_free_credentials(xcred);
  gnutls_global_deinit();

  return 0;
}

0 个答案:

没有答案