11
11
*
12
12
*
13
13
* IDENTIFICATION
14
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.94 2007/02/16 17:07:00 tgl Exp $
14
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.95 2007/10/01 20:30:06 mha Exp $
15
15
*
16
16
* NOTES
17
17
* [ Most of these notes are wrong/obsolete, but perhaps not all ]
111
111
112
112
#ifdef USE_SSL
113
113
#include <openssl/ssl.h>
114
+ #include <openssl/bio.h>
114
115
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L )
115
116
#include <openssl/conf.h>
116
117
#endif
@@ -567,6 +568,10 @@ verify_peer(PGconn *conn)
567
568
* This callback is only called when the server wants a
568
569
* client cert.
569
570
*
571
+ * Since BIO functions can set OpenSSL error codes, we must
572
+ * reset the OpenSSL error stack on *every* exit from this
573
+ * function once we've started using BIO.
574
+ *
570
575
* Must return 1 on success, 0 on no data or error.
571
576
*/
572
577
static int
@@ -579,8 +584,9 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
579
584
struct stat buf2 ;
580
585
#endif
581
586
char fnbuf [MAXPGPATH ];
582
- FILE * fp ;
583
- PGconn * conn = (PGconn * ) SSL_get_app_data (ssl );
587
+ FILE * fp ;
588
+ BIO * bio ;
589
+ PGconn * conn = (PGconn * ) SSL_get_app_data (ssl );
584
590
char sebuf [256 ];
585
591
586
592
if (!pqGetHomeDirectory (homedir , sizeof (homedir )))
@@ -590,27 +596,34 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
590
596
return 0 ;
591
597
}
592
598
599
+ /* save OpenSSL error stack */
600
+ ERR_set_mark ();
601
+
593
602
/* read the user certificate */
594
603
snprintf (fnbuf , sizeof (fnbuf ), "%s/%s" , homedir , USER_CERT_FILE );
595
- if ((fp = fopen (fnbuf , "r" )) == NULL )
604
+ if ((bio = BIO_new_file (fnbuf , "r" )) == NULL )
596
605
{
597
606
printfPQExpBuffer (& conn -> errorMessage ,
598
607
libpq_gettext ("could not open certificate file \"%s\": %s\n" ),
599
608
fnbuf , pqStrerror (errno , sebuf , sizeof (sebuf )));
609
+ ERR_pop_to_mark ();
600
610
return 0 ;
601
611
}
602
- if (PEM_read_X509 (fp , x509 , NULL , NULL ) == NULL )
612
+
613
+ if (PEM_read_bio_X509 (bio , x509 , NULL , NULL ) == NULL )
603
614
{
604
615
char * err = SSLerrmessage ();
605
616
606
617
printfPQExpBuffer (& conn -> errorMessage ,
607
618
libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
608
619
fnbuf , err );
609
620
SSLerrfree (err );
610
- fclose (fp );
621
+ BIO_free (bio );
622
+ ERR_pop_to_mark ();
611
623
return 0 ;
612
624
}
613
- fclose (fp );
625
+
626
+ BIO_free (bio );
614
627
615
628
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L ) && !defined(OPENSSL_NO_ENGINE )
616
629
if (getenv ("PGSSLKEY" ))
@@ -625,6 +638,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
625
638
{
626
639
printfPQExpBuffer (& conn -> errorMessage ,
627
640
libpq_gettext ("invalid value of PGSSLKEY environment variable\n" ));
641
+ ERR_pop_to_mark ();
628
642
return 0 ;
629
643
}
630
644
@@ -640,8 +654,9 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
640
654
engine_str , err );
641
655
SSLerrfree (err );
642
656
free (engine_str );
657
+ ERR_pop_to_mark ();
643
658
return 0 ;
644
- }
659
+ }
645
660
646
661
* pkey = ENGINE_load_private_key (engine_ptr , engine_colon + 1 ,
647
662
NULL , NULL );
@@ -654,8 +669,9 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
654
669
engine_colon + 1 , engine_str , err );
655
670
SSLerrfree (err );
656
671
free (engine_str );
672
+ ERR_pop_to_mark ();
657
673
return 0 ;
658
- }
674
+ }
659
675
free (engine_str );
660
676
}
661
677
else
@@ -668,6 +684,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
668
684
printfPQExpBuffer (& conn -> errorMessage ,
669
685
libpq_gettext ("certificate present, but not private key file \"%s\"\n" ),
670
686
fnbuf );
687
+ ERR_pop_to_mark ();
671
688
return 0 ;
672
689
}
673
690
#ifndef WIN32
@@ -677,37 +694,46 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
677
694
printfPQExpBuffer (& conn -> errorMessage ,
678
695
libpq_gettext ("private key file \"%s\" has wrong permissions\n" ),
679
696
fnbuf );
697
+ ERR_pop_to_mark ();
680
698
return 0 ;
681
699
}
682
700
#endif
683
- if ((fp = fopen (fnbuf , "r" )) == NULL )
701
+
702
+ if ((bio = BIO_new_file (fnbuf , "r" )) == NULL )
684
703
{
685
704
printfPQExpBuffer (& conn -> errorMessage ,
686
705
libpq_gettext ("could not open private key file \"%s\": %s\n" ),
687
706
fnbuf , pqStrerror (errno , sebuf , sizeof (sebuf )));
707
+ ERR_pop_to_mark ();
688
708
return 0 ;
689
709
}
690
710
#ifndef WIN32
711
+ BIO_get_fp (bio , & fp );
691
712
if (fstat (fileno (fp ), & buf2 ) == -1 ||
692
713
buf .st_dev != buf2 .st_dev || buf .st_ino != buf2 .st_ino )
693
714
{
694
715
printfPQExpBuffer (& conn -> errorMessage ,
695
716
libpq_gettext ("private key file \"%s\" changed during execution\n" ), fnbuf );
717
+ ERR_pop_to_mark ();
696
718
return 0 ;
697
719
}
698
720
#endif
699
- if (PEM_read_PrivateKey (fp , pkey , NULL , NULL ) == NULL )
721
+
722
+ if (PEM_read_bio_PrivateKey (bio , pkey , NULL , NULL ) == NULL )
700
723
{
701
724
char * err = SSLerrmessage ();
702
725
703
726
printfPQExpBuffer (& conn -> errorMessage ,
704
727
libpq_gettext ("could not read private key file \"%s\": %s\n" ),
705
728
fnbuf , err );
706
729
SSLerrfree (err );
707
- fclose (fp );
730
+
731
+ BIO_free (bio );
732
+ ERR_pop_to_mark ();
708
733
return 0 ;
709
734
}
710
- fclose (fp );
735
+
736
+ BIO_free (bio );
711
737
}
712
738
713
739
/* verify that the cert and key go together */
@@ -719,9 +745,12 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
719
745
libpq_gettext ("certificate does not match private key file \"%s\": %s\n" ),
720
746
fnbuf , err );
721
747
SSLerrfree (err );
748
+ ERR_pop_to_mark ();
722
749
return 0 ;
723
750
}
724
751
752
+ ERR_pop_to_mark ();
753
+
725
754
return 1 ;
726
755
}
727
756
0 commit comments