I came here since fsockopen() does not support any SSL certificate checking in PHP5.
while curl is nice, I use stream_socket_client() to make XML-RPC POST requests via HTTPS and since I have not found any PHP code around that does this, I'll attach an example that also includes HTTP-Digest Auth (eg. trac's WikiRPCInterface2):
<?php
function httpPost($host, $path, $data_to_send,
                  $opts=array('cert'=>"", 'headers'=>0, 'transport' =>'ssl', 'port'=>443),
                  $auth=array('username'=>"", 'password'=>"", 'type'=>"")
                 ) {
  $transport=''; $port=80;
  if (!empty($opts['transport'])) $transport=$opts['transport'];
  if (!empty($opts['port'])) $port=$opts['port'];
  $remote=$transport.'://'.$host.':'.$port;
  $context = stream_context_create();
  $result = stream_context_set_option($context, 'ssl', 'verify_host', true);
  if (!empty($opts['cert'])) {
    $result = stream_context_set_option($context, 'ssl', 'cafile', $opts['cert']);
    $result = stream_context_set_option($context, 'ssl', 'verify_peer', true);
  } else {
    $result = stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
  }
  $fp = stream_socket_client($remote, $err, $errstr, 60, STREAM_CLIENT_CONNECT, $context);
  if (!$fp) {
    trigger_error('httpPost error: '.$errstr);
    return NULL;
  }
  $req='';
  $req.="POST $path HTTP/1.1\r\n";
  $req.="Host: $host\r\n";
  if ($auth['type']=='basic' && !empty($auth['username'])) {
    $req.="Authorization: Basic ";
    $req.=base64_encode($auth['username'].':'.$auth['password'])."\r\n";
  }
  elseif ($auth['type']=='digest' && !empty($auth['username'])) {
    $req.='Authorization: Digest ';
    foreach ($auth as $k => $v) {
      if (empty($k) || empty($v)) continue;
      if ($k=='password') continue;
      $req.=$k.'="'.$v.'", ';
    }
    $req.="\r\n";
  }
  $req.="Content-type: text/xml\r\n";
  $req.='Content-length: '. strlen($data_to_send) ."\r\n";
  $req.="Connection: close\r\n\r\n";
  fputs($fp, $req);
  fputs($fp, $data_to_send);
  while(!feof($fp)) { $res .= fgets($fp, 128); }
  fclose($fp);
  if ($auth['type']!='nodigest'
        && !empty($auth['username'])
        && $auth['type']!='digest' && preg_match("/^HTTP\/[0-9\.]* 401 /", $res)) {
    if (1 == preg_match("/WWW-Authenticate: Digest ([^\n\r]*)\r\n/Us", $res, $matches)) {
      foreach (split(",", $matches[1]) as $i) {
        $ii=split("=",trim($i),2);
        if (!empty($ii[1]) && !empty($ii[0])) {
          $auth[$ii[0]]=preg_replace("/^\"/",'', preg_replace("/\"$/",'', $ii[1]));
        }
      }
      $auth['type']='digest';
      $auth['uri']='https://'.$host.$path;
      $auth['cnonce']=randomNonce();
      $auth['nc']=1;
      $a1=md5($auth['username'].':'.$auth['realm'].':'.$auth['password']);
      $a2=md5('POST'.':'.$auth['uri']);
      $auth['response']=md5($a1.':'
                           .$auth['nonce'].':'.$auth['nc'].':'
                           .$auth['cnonce'].':'.$auth['qop'].':'.$a2);
      return httpPost($host, $path, $data_to_send, $opts, $auth);
    }
  }
  if (1 != preg_match("/^HTTP\/[0-9\.]* ([0-9]{3}) ([^\r\n]*)/", $res, $matches)) {
    trigger_error('httpPost: invalid HTTP reply.');
    return NULL;
  }
  if ($matches[1] != '200') {
    trigger_error('httpPost: HTTP error: '.$matches[1].' '.$matches[2]);
    return NULL;
  }
  if (!$opts['headers']) {
    $res=preg_replace("/^.*\r\n\r\n/Us",'',$res);
  }
  return $res;
}
?>