Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package google-guest-oslogin for
openSUSE:Factory checked in at 2023-08-16 14:17:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/google-guest-oslogin (Old)
and /work/SRC/openSUSE:Factory/.google-guest-oslogin.new.11712 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "google-guest-oslogin"
Wed Aug 16 14:17:45 2023 rev:19 rq:1104089 version:20230808.00
Changes:
--------
---
/work/SRC/openSUSE:Factory/google-guest-oslogin/google-guest-oslogin.changes
2023-05-10 16:18:03.150807190 +0200
+++
/work/SRC/openSUSE:Factory/.google-guest-oslogin.new.11712/google-guest-oslogin.changes
2023-08-16 14:17:46.659263726 +0200
@@ -1,0 +2,6 @@
+Tue Aug 15 13:53:44 UTC 2023 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 20230808.00
+ * byoid: extract and apply the ca fingerprint to policy call (#106)
+
+-------------------------------------------------------------------
Old:
----
google-guest-oslogin-20230502.00.tar.gz
New:
----
google-guest-oslogin-20230808.00.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ google-guest-oslogin.spec ++++++
--- /var/tmp/diff_new_pack.5PLPIA/_old 2023-08-16 14:17:47.971272912 +0200
+++ /var/tmp/diff_new_pack.5PLPIA/_new 2023-08-16 14:17:48.011273191 +0200
@@ -19,7 +19,7 @@
%{!?_pam_moduledir: %define _pam_moduledir %{_pamdir}}
Name: google-guest-oslogin
-Version: 20230502.00
+Version: 20230808.00
Release: 0
Summary: Google Cloud Guest OS Login
License: Apache-2.0
++++++ google-guest-oslogin-20230502.00.tar.gz ->
google-guest-oslogin-20230808.00.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/guest-oslogin-20230502.00/.gitignore
new/guest-oslogin-20230808.00/.gitignore
--- old/guest-oslogin-20230502.00/.gitignore 1970-01-01 01:00:00.000000000
+0100
+++ new/guest-oslogin-20230808.00/.gitignore 2023-08-08 20:00:56.000000000
+0200
@@ -0,0 +1,7 @@
+*.so
+*.o
+google_authorized_keys
+google_authorized_keys_sk
+google_oslogin_nss_cache
+test/sshca_runner
+test/test_detail.xml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/guest-oslogin-20230502.00/src/Makefile
new/guest-oslogin-20230808.00/src/Makefile
--- old/guest-oslogin-20230502.00/src/Makefile 2023-05-02 20:42:44.000000000
+0200
+++ new/guest-oslogin-20230808.00/src/Makefile 2023-08-08 20:00:56.000000000
+0200
@@ -1,7 +1,7 @@
SHELL = /bin/sh
TOPDIR = $(realpath ..)
-CPPFLAGS = -Iinclude -I/usr/include/json-c
+CPPFLAGS = -Iinclude -I/usr/include/json-c -I$(TOPDIR)/third_party/include
FLAGS = -fPIC -Wall -g
CFLAGS = $(FLAGS) -Wstrict-prototypes
CXXFLAGS = $(FLAGS)
@@ -53,10 +53,10 @@
# PAM modules
-$(PAM_LOGIN): pam/pam_oslogin_login.o oslogin_utils.o
+$(PAM_LOGIN): pam/pam_oslogin_login.o pam/oslogin_sshca.o oslogin_utils.o
include/oslogin_sshca.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -shared $^ -o $@ $(PAMLIBS)
-$(PAM_ADMIN): pam/pam_oslogin_admin.o oslogin_utils.o
+$(PAM_ADMIN): pam/pam_oslogin_admin.o pam/oslogin_sshca.o oslogin_utils.o
include/oslogin_sshca.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -shared $^ -o $@ $(PAMLIBS)
# Utilities.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/guest-oslogin-20230502.00/src/include/oslogin_sshca.h
new/guest-oslogin-20230808.00/src/include/oslogin_sshca.h
--- old/guest-oslogin-20230502.00/src/include/oslogin_sshca.h 1970-01-01
01:00:00.000000000 +0100
+++ new/guest-oslogin-20230808.00/src/include/oslogin_sshca.h 2023-08-08
20:00:56.000000000 +0200
@@ -0,0 +1,53 @@
+// Copyright 2023 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _OSLOGIN_SSHCA_H_
+#define _OSLOGIN_SSHCA_H_ 1
+
+#include <compat.h>
+#include <ctype.h>
+#include <security/pam_modules.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syslog.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SKIP_BYTES(b, l, s) \
+ { \
+ b = b + s; \
+ l = l - s; \
+ } \
+
+#define SKIP_UINT64(b, l) \
+ SKIP_BYTES(b, l, 8) \
+
+#define SKIP_UINT32(b, l) \
+ SKIP_BYTES(b, l, 4) \
+
+#define PEEK_U32(p) \
+ (((u_int32_t)(((const u_char *)(p))[0]) << 24) | \
+ ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \
+ ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \
+ (u_int32_t)(((const u_char *)(p))[3]))
+
+int sshca_get_byoid_fingerprint(pam_handle_t* pamh, const char *blob, char
**fingerprint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/guest-oslogin-20230502.00/src/pam/oslogin_sshca.cc
new/guest-oslogin-20230808.00/src/pam/oslogin_sshca.cc
--- old/guest-oslogin-20230502.00/src/pam/oslogin_sshca.cc 1970-01-01
01:00:00.000000000 +0100
+++ new/guest-oslogin-20230808.00/src/pam/oslogin_sshca.cc 2023-08-08
20:00:56.000000000 +0200
@@ -0,0 +1,322 @@
+// Copyright 2023 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <oslogin_sshca.h>
+#include <openbsd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct sshca_type {
+ const char *type;
+ int (*skip_custom_fields)(char **buff, size_t *blen);
+} sshca_type;
+
+static int sshca_dsa_skip_fields(char **buff, size_t *blen);
+static int sshca_ecdsa_skip_fields(char **buff, size_t *blen);
+static int sshca_ed25519_skip_fields(char **buff, size_t *blen);
+static int sshca_rsa_skip_fields(char **buff, size_t *blen);
+
+static sshca_type sshca_impl[] = {
+ {"[email protected]", sshca_ecdsa_skip_fields},
+ {"[email protected]", sshca_ecdsa_skip_fields},
+ {"[email protected]", sshca_ecdsa_skip_fields},
+ {"[email protected]", sshca_rsa_skip_fields},
+ {"[email protected]", sshca_rsa_skip_fields},
+ {"[email protected]", sshca_dsa_skip_fields},
+ {"[email protected]", sshca_ed25519_skip_fields},
+ {"[email protected]", sshca_rsa_skip_fields},
+ { },
+};
+
+static int
+sshca_get_string(char **buff, size_t *blen, char **ptr, size_t *len_ptr) {
+ u_int32_t len;
+
+ if (*blen < 4) {
+ return -1;
+ }
+
+ len = PEEK_U32(*buff);
+ if ((*blen - 4) < len) {
+ return -1;
+ }
+
+ if (len_ptr != NULL) {
+ *len_ptr = len;
+ }
+
+ *buff = *buff + 4;
+ *blen = *blen - 4;
+
+ if (ptr != NULL) {
+ *ptr = (char *)malloc(len + 1);
+ memcpy(*ptr, *buff, len);
+ ((char *)*ptr)[len] = '\0';
+ }
+
+ // Always move the buffer forward.
+ *buff = *buff + len;
+
+ return 0;
+}
+
+static sshca_type*
+sshca_get_implementation(const char *type) {
+ sshca_type *iter;
+
+ for (iter = sshca_impl; iter->type != NULL; iter++) {
+ if (strcasecmp(type, iter->type) == 0) {
+ return iter;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+sshca_rsa_skip_fields(char **buff, size_t *blen) {
+ // Skip e.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ // Skip n.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sshca_dsa_skip_fields(char **buff, size_t *blen) {
+ // Skip p.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ // Skip q.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ // Skip g.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ // Skip y.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sshca_ed25519_skip_fields(char **buff, size_t *blen) {
+ // Skip pk.
+ return sshca_get_string(buff, blen, NULL, NULL);
+}
+
+static int
+sshca_ecdsa_skip_fields(char **buff, size_t *blen) {
+ // Skip curve.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ // Skip public key.
+ if (sshca_get_string(buff, blen, NULL, NULL) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sshca_get_extension(pam_handle_t *pamh, const char *key, size_t k_len, char
**exts) {
+ sshca_type* impl = NULL;
+ size_t n_len, t_len, tmp_exts_len, ret = -1;
+ char *tmp_exts, *tmp_head, *type, *key_b64, *head;
+
+ head = tmp_head = NULL;
+
+ head = key_b64 = (char *)calloc(k_len, sizeof(char));
+ if (key_b64 == NULL) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Could not allocate b64 buffer.");
+ goto out;
+ }
+
+ if ((n_len = b64_pton(key, (u_char *)key_b64, k_len)) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Could encode buffer b64.");
+ goto out;
+ }
+
+ // Invalid key (?)
+ if (n_len <= 4) {
+ goto out;
+ }
+
+ if (sshca_get_string(&key_b64, &n_len, &type, &t_len) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Could not get cert's type string.");
+ goto out;
+ }
+
+ impl = sshca_get_implementation(type);
+ if (impl == NULL) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Invalid cert type: %s.", type);
+ goto out;
+ }
+
+ // Skip nonce for all types of certificates.
+ if (sshca_get_string(&key_b64, &n_len, NULL, NULL) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to skip cert's \"nonce\" field.");
+ goto out;
+ }
+
+ // Skip type specific fields.
+ if (impl->skip_custom_fields(&key_b64, &n_len) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to skip cert's custom/specific fields.");
+ goto out;
+ }
+
+ // Skip serial.
+ SKIP_UINT64(key_b64, n_len);
+
+ // Skip type.
+ SKIP_UINT32(key_b64, n_len);
+
+ // Skip key id.
+ if (sshca_get_string(&key_b64, &n_len, NULL, NULL) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to skip cert's \"key id\" field.");
+ goto out;
+ }
+
+ // Skip valid principals.
+ if (sshca_get_string(&key_b64, &n_len, NULL, NULL) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to skip cert's \"valid principals\" "
+ "field.");
+ goto out;
+ }
+
+ // Skip valid after.
+ SKIP_UINT64(key_b64, n_len);
+
+ // Skip valid before.
+ SKIP_UINT64(key_b64, n_len);
+
+ // Skip critical options.
+ if (sshca_get_string(&key_b64, &n_len, NULL, NULL) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to skip cert's \"critical options\" "
+ "field.");
+ goto out;
+ }
+
+ // Get extensions buffer.
+ if (sshca_get_string(&key_b64, &n_len, &tmp_exts, &tmp_exts_len) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to get cert's \"extensions\" field.");
+ goto out;
+ }
+
+ // The field extensions is a self described/sized buffer.
+ tmp_head = tmp_exts;
+ if (sshca_get_string(&tmp_exts, &tmp_exts_len, exts, &ret) < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Failed to read google's extension.");
+ goto out;
+ }
+
+out:
+ free(tmp_head);
+ free(type);
+ free(head);
+
+ return ret;
+}
+
+static size_t
+sshca_split_key(const char *blob, char **out) {
+ int i, len, k_start;
+ char *key = NULL;
+
+ len = 0;
+ k_start = 0;
+
+ for (i = 0; blob[i] != '\0'; i++) {
+ if (blob[i] == ' ' && key == NULL) {
+ k_start = i + 1;
+ key = (char *)blob + i + 1;
+ } else if (blob[i] == ' ' && key != NULL) {
+ len = i;
+ }
+ }
+
+ *out = strndup(key, len - k_start);
+ return len;
+}
+
+static size_t
+sshca_extract_fingerprint(const char *extension, char **out) {
+ int i = 0;
+
+ if (extension == NULL || strstr(extension, "[email protected]=") ==
NULL) {
+ return 0;
+ }
+
+ for (i = 0; extension[i] != '\0'; i++) {
+ if (extension[i] == '=') {
+ *out = strdup(extension + i + 1);
+ }
+ }
+
+ return i;
+}
+
+int
+sshca_get_byoid_fingerprint(pam_handle_t *pamh, const char *blob, char
**fingerprint) {
+ size_t f_len, k_len, exts_len = -1;
+ char *key, *exts = NULL;
+
+ k_len = sshca_split_key(blob, &key);
+ if (k_len <= 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Could not split ssh ca cert.");
+ goto out;
+ }
+
+ exts_len = sshca_get_extension(pamh, key, k_len, &exts);
+ if (exts_len < 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Could not parse/extract extension"
+ "from ssh ca cert.");
+ goto out;
+ }
+
+ f_len = sshca_extract_fingerprint(exts, fingerprint);
+ if (f_len == 0) {
+ PAM_SYSLOG(pamh, LOG_ERR, "Could not parse/extract fingerprint"
+ "from ssh ca cert's extension.");
+ goto out;
+ }
+
+out:
+ free(exts);
+ free(key);
+
+ return f_len;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/guest-oslogin-20230502.00/src/pam/pam_oslogin_admin.cc
new/guest-oslogin-20230808.00/src/pam/pam_oslogin_admin.cc
--- old/guest-oslogin-20230502.00/src/pam/pam_oslogin_admin.cc 2023-05-02
20:42:44.000000000 +0200
+++ new/guest-oslogin-20230808.00/src/pam/pam_oslogin_admin.cc 2023-08-08
20:00:56.000000000 +0200
@@ -27,6 +27,7 @@
#include <compat.h>
#include <oslogin_utils.h>
+#include <oslogin_sshca.h>
using std::string;
@@ -48,7 +49,8 @@
// The return value for this module should generally be ignored. By default
we
// will return PAM_SUCCESS.
int pam_result = PAM_SUCCESS;
- const char *user_name;
+ const char *user_name, *ssh_auth_info;
+ char *fingerprint = NULL;
if ((pam_result = pam_get_user(pamh, &user_name, NULL)) != PAM_SUCCESS) {
PAM_SYSLOG(pamh, LOG_INFO, "Could not get pam user.");
@@ -74,6 +76,17 @@
url << kMetadataServerUrl << "authorize?email=" << UrlEncode(email)
<< "&policy=adminLogin";
+ ssh_auth_info = pam_getenv(pamh, "SSH_AUTH_INFO_0");
+ if (ssh_auth_info != NULL && strlen(ssh_auth_info) > 0) {
+ size_t fp_len = sshca_get_byoid_fingerprint(pamh, ssh_auth_info,
&fingerprint);
+ // Don't try to add fingerprint parameter to policy call if we don't find
it
+ // in the certificate.
+ if (fp_len > 0) {
+ url << "&fingerprint=" << fingerprint;
+ free(fingerprint);
+ }
+ }
+
string filename = kSudoersDir;
filename.append(user_name);
struct stat buffer;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/guest-oslogin-20230502.00/src/pam/pam_oslogin_login.cc
new/guest-oslogin-20230808.00/src/pam/pam_oslogin_login.cc
--- old/guest-oslogin-20230502.00/src/pam/pam_oslogin_login.cc 2023-05-02
20:42:44.000000000 +0200
+++ new/guest-oslogin-20230808.00/src/pam/pam_oslogin_login.cc 2023-08-08
20:00:56.000000000 +0200
@@ -28,6 +28,7 @@
#include <compat.h>
#include <oslogin_utils.h>
+#include <oslogin_sshca.h>
using oslogin_utils::ContinueSession;
using oslogin_utils::GetUser;
@@ -48,7 +49,8 @@
PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const char** argv) {
- const char *user_name;
+ const char *user_name, *ssh_auth_info;
+ char *fingerprint = NULL;
if (pam_get_user(pamh, &user_name, NULL) != PAM_SUCCESS) {
PAM_SYSLOG(pamh, LOG_INFO, "Could not get pam user.");
@@ -96,6 +98,17 @@
url << kMetadataServerUrl << "authorize?email=" << UrlEncode(email)
<< "&policy=login";
+ ssh_auth_info = pam_getenv(pamh, "SSH_AUTH_INFO_0");
+ if (ssh_auth_info != NULL && strlen(ssh_auth_info) > 0) {
+ size_t fp_len = sshca_get_byoid_fingerprint(pamh, ssh_auth_info,
&fingerprint);
+ // Don't try to add fingerprint parameter to policy call if we don't find
it
+ // in the certificate.
+ if (fp_len > 0) {
+ url << "&fingerprint=" << fingerprint;
+ free(fingerprint);
+ }
+ }
+
if (!HttpGet(url.str(), &response, &http_code)) {
PAM_SYSLOG(pamh, LOG_INFO, "Failed to validate organization user %s "
"has login permission.", user_name);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/guest-oslogin-20230502.00/test/Makefile
new/guest-oslogin-20230808.00/test/Makefile
--- old/guest-oslogin-20230502.00/test/Makefile 2023-05-02 20:42:44.000000000
+0200
+++ new/guest-oslogin-20230808.00/test/Makefile 2023-08-08 20:00:56.000000000
+0200
@@ -6,6 +6,7 @@
TEST_RUNNER = ./test_runner --gtest_output=xml
NEW_TEST_RUNNER = ./new_test_runner --gtest_output=xml
+SSHCA_TEST_RUNNER = ./sshca_runner --gtest_output=xml
--gtest_filter="SSHCATests.*"
CPPFLAGS += -I$(TOPDIR)/src/include -I/usr/include/json-c -I$(GTEST_DIR)
-isystem $(GTEST_DIR)/include
CXXFLAGS += -g -Wall -Wextra -std=c++11
LDLIBS = -lcurl -ljson-c -lpthread
@@ -25,6 +26,12 @@
test_runner: oslogin_utils_test.o $(TOPDIR)/src/oslogin_utils.o gtest-all.o
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $^ -o $@ $(LDLIBS)
+sshca_runner: oslogin_sshca_test.o gtest-all.o
$(TOPDIR)/src/pam/oslogin_sshca.o
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) $^ -o $@ $(LDLIBS) -lpam
+
+sshca_tests: sshca_runner
+ $(SSHCA_TEST_RUNNER)
+
new_test_runner: oslogin_test.o gtest-all.o
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $^ -o $@ $(LDLIBS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/guest-oslogin-20230502.00/test/oslogin_sshca_test.cc
new/guest-oslogin-20230808.00/test/oslogin_sshca_test.cc
--- old/guest-oslogin-20230502.00/test/oslogin_sshca_test.cc 1970-01-01
01:00:00.000000000 +0100
+++ new/guest-oslogin-20230808.00/test/oslogin_sshca_test.cc 2023-08-08
20:00:56.000000000 +0200
@@ -0,0 +1,273 @@
+// Copyright 2023 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <errno.h>
+#include <gtest/gtest.h>
+#include <oslogin_sshca.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using std::string;
+using std::vector;
+
+namespace oslogin_utils {
+
+#define VALID_ECDSA_SINGLE_EXT "[email protected] " \
+ "AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg1yMhf" \
+ "NVBe4etWEQNDmtxhsAD+YAb7fl/Bn0Z+GGEE9EAAAAIbmlzdHAyNTYAAABBBJ+nM2cR4B" \
+ "FHbmokUIScpTaSkx/F1QS2KfIx6z4wcpUmjzKtbP0KFw12mMUiNHzlNBD0B2RnX54uN+k" \
+ "bjYGUdSAAAAAAAAAAAAAAAAEAAAAScGFudGhlb24uc2l0YXIubWlnAAAAFgAAABJwYW50" \
+ "aGVvbi5zaXRhci5taWcAAAAAAAAAAP//////////AAAAAAAAAEMAAAA7ZmluZ2VycHJpb" \
+ "nRAZ29vZ2xlLmNvbT1iODZkYjRjYS0wOWZkLTQyOWUtYjEyMS1hMTI3OTk2MTQwMzIAAA" \
+ "AAAAAAAAAAAZcAAAAHc3NoLXJzYQAAAAMBAAEAAAGBAKgQiEGiszewwIeTPZv1/wwQF7K" \
+ "JeStkko6w7tcUXRUFWc1ajBUXjEQAxv64JSC+RvlFn7NTVxwzHb+lnbU9+74xfLKB9pqb" \
+ "XwiO8HNr4OhLdqfn6x8alfUwsezJzhdBs86o9B9YTFwX2UMJ0c3rZ/0Do6V3WlckMFiPh" \
+ "ZiXyiW3pYve+7kj9EZ/WJMAdxTnLPNF03azy3+siyVOWL2zkL8DVscpVVQ51ln15mwvI4" \
+ "/e0BVQbP0rtfGIjVOaUM4PyLAfTwg/GPpXroNefvRaxF1scXIjxVQTgm7EauWUyl0i4A1" \
+ "sQVEoXWyxQsgdGd6+BTZ3khJCAVSnLTeIhvP9utGJhSLvuJFZu1S1oA1s1/pvpDE9Nfc1" \
+ "QT14pWKGUU05Z8yPuBSwbbPqQZvSBhCsVNC5wN6AEkiIsKRJkcSXZIqGQpY9CUAJi9GxS" \
+ "R7ATiSy9GAJypHkHNDmJeBEfxYk7Z7jWBZ39HikmAaUfPYzpfjc0nPxYMkMKKy5wnftia" \
+ "pVxwAAAZQAAAAMcnNhLXNoYTItNTEyAAABgA4z6rSDNPKG9ae/C11q0U1CsPscK8tXFuK" \
+ "surZNXnfAbNwPp8/7x5pamgq5119PnAacll29U9+L+dYwmU8NsJgd1nnQPXh2hLdGs828" \
+ "hMOxSgwj35YSzToSulwmOxG7uOYI056WBc3ZZtcxBqvHThLAo6J2TnURicNMvID42ofqQ" \
+ "H2Wgozg1AOyHwCDdkrG304NoSfx76tIf/RjLu7yedhhu1x0hbz4DsLLKlm5vVI8jQvLB7" \
+ "iz37LMdvftX+Zqnf2EWDT7GspchbrCStH15GXaMCXwyObbDmKkYLz77XckBAQLjm0C6f2" \
+ "+f8UxtWzZDvqVFr/iIpivaRUhpGMYNED43XAKR/8uAMKA9d7mB8lD9wMBmRxbG4qDTM4q" \
+ "7Q539h7IPMoTRN82VL0v1KPVW8uWqqSjVFdrr2DshitTALMwXpf4VIxw/XuOV5ALNTCan" \
+ "bcetrgglFiujUFlIdxkHMmsIxHM88wEnJAlETd7zl9WR/FgQYn3y2dZz9VKoheJdg== " \
+ "pantheon.sitar.mig" \
+
+#define INVALID_ECDSA_NO_FP "[email protected] A" \
+ "AAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgxlbtL" \
+ "/mjYXEgsXjl7GZgpvIFncxbfmjPYVewm1sdXo4AAAAIbmlzdHAyNTYAAABBBMYdGLr6M" \
+ "102qgBeJ3CanDi0WV1vGif2jMMv1ldtN0+wbDztYdtUu8iop/tN46wFVbfmSzyx/R2YL" \
+ "bvQ+z2k/sYAAAAAAAAAAAAAAAEAAAAWZmluZ2VycHJpbnRAZ29vZ2xlLmNvbQAAABoAA" \
+ "AAWZmluZ2VycHJpbnRAZ29vZ2xlLmNvbQAAAABk0UUMAAAAAGaxJ2gAAAAAAAAAAAAAA" \
+ "AAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPoCTDKl0" \
+ "jZG3V2P14+PDbYrD0sDBsKwYaZEn85tM6mmGEY1yHg/VI76O27xTqE56PJECph1eKmo4" \
+ "YA/ch8wwewAAABkAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABJAAAAIQCN6KRgSVKYH" \
+ "pM3dlil8jDXlpL4U1JSmP3MeHX0OKcpHgAAACAYiWa3KrreEzN+VrnuhwStH70bvH9Qm" \
+ "6Va6a0IcMrMkA== [email protected]" \
+
+#define INVALID_ECDSA_NON_CERT "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTI" \
+ "tbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMYdGLr6M102qgBeJ3CanDi0WV1vGif2jMM" \
+ "v1ldtN0+wbDztYdtUu8iop/tN46wFVbfmSzyx/R2YLbvQ+z2k/sY= " \
+ "[email protected]" \
+
+#define VALID_RSA_SINGLE_EXT "[email protected] AAAAHHNzaC1yc" \
+ "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" \
+ "GqmJpNjwsqExxW5E= [email protected]" \
+
+#define INVALID_RSA_NO_FP "[email protected] AAAAHHNzaC1yc2Et" \
+ "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 " \
+ "[email protected]" \
+
+#define INVALID_RSA_NON_CERT "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCU/m" \
+ "ydd9mSwlSDv4T3OiL5IHrvSuXpWFvCEDmVyLxBHz1FCwjnk3G5xSt9nGtUyL0KpGt0dyv" \
+ "LU07JGB33cbVnVe1z3373FNKxF8LdwDTEZG6xijXuOi4xfk47arlpk9Pw14qcnVu9on4R" \
+ "m4cSmm5PkyIwTfJsKvOl8oOgZ0HZG7pzYEt+9wUoeGzUE0rsAreNFVB7ZBqHp2ZtdIe5d" \
+ "dbarKAl1JKZuz8EbUmdjBYXsMYLHd0gUd+rvHyaw7p3iJyESaJcqUOQHrecpkLqWiN+TU" \
+ "NZPchE/T19LSP/fQbPCGmqc+mC6YodSEbLkO6JmOaW+knTEc9D6xdozx6Oa4vR " \
+ "[email protected]" \
+
+#define VALID_DSA_SINGLE_EXT "[email protected] AAAAHHNzaC1kc" \
+ "3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgH400e9SzsvaN8OkKvH26sXEJtU/BVc2IBG" \
+ "fdZDHk508AAACBAO9UdOmq7Z0qy86mwsDf07TmXQe7X0TLKbyFSsd2b+jTCzpXy9rBhgg" \
+ "oJlzYzxSQgtR4JaSTauZMiQQViN3cKvHuGfAXIOIMtMHVupNy6WSkcixGrvw6Y0Yr90+e" \
+ "8PXcFw6jwQbFZX4v9zlUuIl067rCrxp1jnhBjxvBZEmpR/ezAAAAFQCO10V2wYXJ7cSo4" \
+ "eEgHB1BnOxbzwAAAIEAzbdt5bgzV164ljY6dimHUUnKUnYEq7VY3gJZSN3YGwMHnIYw94" \
+ "gtNxkhP09SkPn+llAH/NTKq2beu9GizybqIc9Gtfh3AGqYLyWhePZumcUYYShMc7eNUfN" \
+ "RDp1QtWnX/A/HvVsNEdqHW3R9cq5miEWgoUFHOHhLZtUOk1wbJe4AAACAITYKkJACQAoh" \
+ "b9q1Ehxea8qoYaM2ctI3JCN59bbcgP1Tngaq2TcJOup0+AVN5P7ILQGh3s9xngdcQU9RJ" \
+ "XlUh6yHpW0BwkAOAKjX7ASjx4rKOkN0PeT2KtyGWqLcnbFRSQGNQOs+vv3TIUofZosXKT" \
+ "A2EtmjpKcIbfu3lF+J50gAAAAAAAAAAAAAAAEAAAAWZmluZ2VycHJpbnRAZ29vZ2xlLmN" \
+ "vbQAAABoAAAAWZmluZ2VycHJpbnRAZ29vZ2xlLmNvbQAAAABk0SkoAAAAAGaxC5IAAAAA" \
+ "AAAAQwAAADtmaW5nZXJwcmludEBnb29nbGUuY29tPWI4NmRiNGNhLTA5ZmQtNDI5ZS1iM" \
+ "TIxLWExMjc5OTYxNDAzMgAAAAAAAAAAAAABsgAAAAdzc2gtZHNzAAAAgQC1WfAI4qlV3J" \
+ "jY+tsHhQEVJgMVPzrNa94pvSDRc9FYexYHaky6e0zroP8LmxTEZyOzfT9H22lqmIPRHXp" \
+ "dEB5ge7FAO7/QsavsAUQHnpiyaqng4ojgPTQJzY0tuYUkV9a265gZJpqdY0wNLcSJtDFk" \
+ "WtixpTSswF1gGs5maq5ljQAAABUAlYIrD8mImqdRNg7FizxOscWV8WUAAACBAJE9UuRok" \
+ "fqK1ZodxfX0Me1NgS+4rpH9iWqHudpQiR134OUT3w29dtTDKdDjesuOyEDGi17Z5Honsv" \
+ "yktNVzel+F8q6/24NI4VSBnRXi8TkXvK6BjRFJsnVJRMiF8zErd3ihWDmsEXcMJ0X/uQw" \
+ "tBKREhGri3xz1bVVH+Iwb8F5SAAAAgFtqHHk0TP8wLmggYh+i9FDhN+99yt7FxDAGg4di" \
+ "JDkpmo8MUaXmxibghK0c15Tta9hoOUqtArpYdBm0WyfEM/5Us2qVVcJp4Cjrw9OJ3lEgj" \
+ "+OSizEVlMEujCFT/j032c5Y4O3ScCEUDrFjlutMtlUfvPaDGX7yH0mYONAb6p2FAAAANw" \
+ "AAAAdzc2gtZHNzAAAAKH5faM5YTlMn+h2cf99PJ8rjvqQUJoh5yi3a4pkGcr5MJs53Wfi" \
+ "DPaA= [email protected]" \
+
+#define INVALID_DSA_NO_FP "[email protected] AAAAHHNzaC1kc3Mt" \
+ "Y2VydC12MDFAb3BlbnNzaC5jb20AAAAgGrlYnOqQxs/zzfWRcrM7DHrFy653/x7rtOghw" \
+ "R/f3HIAAACBALzWA8yWLownZsO4Tuc4DF6EplCJ1SBSEqMYAEhzrnxjHkoOpJ3Ncs+Zn5" \
+ "jdcnCamkm6KQ4keXkV0xwLthRgLxhUguc9xANV5k2Vft+axWr+cp+KNiGzDjblTUnWzQD" \
+ "5Q/mBpiFKL7EiZski3swpJQs0kGQW2hxbjlr7I0EhM8e1AAAAFQDdVQaUxoK58jpTFdVi" \
+ "gI3yzjtK3wAAAIB1Z8nZ4QEaqSLK5+Xm2LAbn32Do0nGtOkPCWYjZzlcfHt1Hb7gCIe5X" \
+ "gqPZM3hYWuOisKsk2gxxeVyiX6VBuYpCbINduxw8h/7nMyOTFLr01Y282/eHq20XHPLD2" \
+ "2hdY1l44de8EhYrcHRPM7twnFJU0X7og6QNdOnvMXQ+WclWwAAAIAmJmVahDp1Vu22M9t" \
+ "7V4yRYP8Wh3ROletzPrY9kpgTR5QtfZ57QPxN3n2r61iLaPWR0cQ12x4LviBVTsFk87oE" \
+ "9SAxzcDPwyzbSM3ATIzI6TauIVacVFoUdeAy2rjaLUGYcdD745oudXmyXq1VupLHaJC9k" \
+ "ePm8hkeZyf/5F6XBwAAAAAAAAAAAAAAAQAAABZmaW5nZXJwcmludEBnb29nbGUuY29tAA" \
+ "AAGgAAABZmaW5nZXJwcmludEBnb29nbGUuY29tAAAAAGTRQFwAAAAAZrEiogAAAAAAAAA" \
+ "AAAAAAAAAAbEAAAAHc3NoLWRzcwAAAIEA4FZIvoI2syNIyZ34DibfH4Pm3Rf0iKHUIgLR" \
+ "+izM/aP9jDAXRD/c2Tl2cnw4pVJdun2+ByBNkRHQJ+86dMVXhvpIPjoeK4dqJsEBsSj7L" \
+ "ohXMJtdn5LyBpiiyZ4jq7uVeWGm1q7Lh6WeIuBVNLgwoE1/z5RtScGhbHBPb8q7RbcAAA" \
+ "AVAOHoBqU7wxf09lWcarL6SaOAyWJ5AAAAgGLb9fIGSP50+sfKqxSohCU23B3SYCIf7QI" \
+ "1Zjql9FeDY9AfvkzVaiJvA/eoZKwGhG5FbDtA9eyuCfiB5E6VqaShx3Mp3yCKPOaCznrv" \
+ "LKJsqMKC7ReU2obugmMELRmbTdZdQCdvvNrVjqvW54aUIzF4zC9ZKeiKtG6MQ7VP/MrRA" \
+ "AAAgGk5pXHfmjL8vDZIwtWhxm3gdN5TubyKgW1i/nIMDgLhLqLw4//NY86wkGj84MwniT" \
+ "Gf2pB8lGzBPj+ByQIMABe/iMq9uRXLNUFta7PYQKi3UjCoCwv0p88advtwOXRyHu1THxr" \
+ "JDMmmDirJnSYW8I7F9gY4UMldYwy9dyNqwfoQAAAANwAAAAdzc2gtZHNzAAAAKAnb/pHN" \
+ "+YzrU7BOR7qnGs1qJqWhgFKXETMeHxPzpi4ny9tSNlI6c0g= " \
+ "[email protected]" \
+
+#define INVALID_DSA_NON_CERT "ssh-dss AAAAB3NzaC1kc3MAAACBAO9UdOmq7Z0qy8" \
+ "6mwsDf07TmXQe7X0TLKbyFSsd2b+jTCzpXy9rBhggoJlzYzxSQgtR4JaSTauZMiQQViN3" \
+ "cKvHuGfAXIOIMtMHVupNy6WSkcixGrvw6Y0Yr90+e8PXcFw6jwQbFZX4v9zlUuIl067rC" \
+ "rxp1jnhBjxvBZEmpR/ezAAAAFQCO10V2wYXJ7cSo4eEgHB1BnOxbzwAAAIEAzbdt5bgzV" \
+ "164ljY6dimHUUnKUnYEq7VY3gJZSN3YGwMHnIYw94gtNxkhP09SkPn+llAH/NTKq2beu9" \
+ "GizybqIc9Gtfh3AGqYLyWhePZumcUYYShMc7eNUfNRDp1QtWnX/A/HvVsNEdqHW3R9cq5" \
+ "miEWgoUFHOHhLZtUOk1wbJe4AAACAITYKkJACQAohb9q1Ehxea8qoYaM2ctI3JCN59bbc" \
+ "gP1Tngaq2TcJOup0+AVN5P7ILQGh3s9xngdcQU9RJXlUh6yHpW0BwkAOAKjX7ASjx4rKO" \
+ "kN0PeT2KtyGWqLcnbFRSQGNQOs+vv3TIUofZosXKTA2EtmjpKcIbfu3lF+J50g= " \
+ "[email protected]" \
+
+#define VALID_ED25519_SINGLE_EXT "[email protected] AAAAI" \
+ "HNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIDaErnQWEw/jxPD0JUJsEk" \
+ "CtENcE11Zl53QHbxbAgx22AAAAIHs6r2AekiTHmmoJMKxAKtKW4qcGq5Ku1+SJ1NLdZh0" \
+ "1AAAAAAAAAAAAAAABAAAAFmZpbmdlcnByaW50QGdvb2dsZS5jb20AAAAaAAAAFmZpbmdl" \
+ "cnByaW50QGdvb2dsZS5jb20AAAAAZNEqzAAAAABmsQ0IAAAAAAAAAEMAAAA7ZmluZ2Vyc" \
+ "HJpbnRAZ29vZ2xlLmNvbT1iODZkYjRjYS0wOWZkLTQyOWUtYjEyMS1hMTI3OTk2MTQwMz" \
+ "IAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgyxEJdP6tUhJY3J/4bgLpzyUojE9" \
+ "6YKzE2t/RAx5l32kAAABTAAAAC3NzaC1lZDI1NTE5AAAAQNEBsSEvp5tVMbKUsjIZ0jEa" \
+ "Yv0T0U/GZoCiLfVm3pcXV3RA8aze+y/pbjv+MOxjmAb4KbRH31/S34UALsyGwQM= fing" \
+ "[email protected]" \
+
+#define INVALID_ED25519_NO_FP "[email protected] AAAAIHNz" \
+ "aC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIDDgIXa9QLFY7RpSNnWDm3Saq" \
+ "YZ5HGcpzHq9hdv64nqXAAAAIKfDRdZjpCb2YVsmhs286hQTH7JFctizNC0W7UQKfruSAA" \
+ "AAAAAAAAAAAAABAAAAFmZpbmdlcnByaW50QGdvb2dsZS5jb20AAAAaAAAAFmZpbmdlcnB" \
+ "yaW50QGdvb2dsZS5jb20AAAAAZNFCeAAAAABmsSTsAAAAAAAAAAAAAAAAAAAAMwAAAAtz" \
+ "c2gtZWQyNTUxOQAAACBTEPiuWCgwX9JhFzMNLex4d9uRtdWfUg0OCAdH6nVbsAAAAFMAA" \
+ "AALc3NoLWVkMjU1MTkAAABAt2CPRZos3Lna+44LwI6ON8rRktxAqz1S4nUf+IwrG83Wbv" \
+ "nEvvZ2plHLTAU7GP2ZMedVKoXB9KXB2vNBVjt9Cg== [email protected]" \
+
+#define INVALID_ED25519_NON_CERT "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH" \
+ "s6r2AekiTHmmoJMKxAKtKW4qcGq5Ku1+SJ1NLdZh01 [email protected]" \
+
+TEST(SSHCATests, TestValidSingleExtCert) {
+ struct {
+ const char *key;
+ } *iter, tests[] = {
+ {VALID_RSA_SINGLE_EXT},
+ {VALID_DSA_SINGLE_EXT},
+ {VALID_ECDSA_SINGLE_EXT},
+ {VALID_ED25519_SINGLE_EXT},
+ { NULL },
+ };
+
+ for (iter = tests; iter->key != NULL; iter++) {
+ char *fingerprint = NULL;
+ size_t len = sshca_get_byoid_fingerprint(NULL, iter->key, &fingerprint);
+ ASSERT_GT(len, 0);
+ ASSERT_STREQ(fingerprint, "b86db4ca-09fd-429e-b121-a12799614032");
+ free(fingerprint);
+ }
+}
+
+TEST(SSHCATests, TestInvalidNoFpCert) {
+ struct {
+ const char *key;
+ } *iter, tests[] = {
+ {INVALID_DSA_NO_FP},
+ {INVALID_DSA_NON_CERT},
+ {INVALID_ED25519_NO_FP},
+ {INVALID_ED25519_NON_CERT},
+ {INVALID_RSA_NO_FP},
+ {INVALID_RSA_NON_CERT},
+ {INVALID_ECDSA_NO_FP},
+ {INVALID_ECDSA_NON_CERT},
+ { NULL },
+ };
+
+ for (iter = tests; iter->key != NULL; iter++) {
+ char *fingerprint = NULL;
+ size_t len = sshca_get_byoid_fingerprint(NULL, iter->key, &fingerprint);
+ ASSERT_EQ(len, 0);
+ ASSERT_STREQ(fingerprint, NULL);
+ free(fingerprint);
+ }
+}
+
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/guest-oslogin-20230502.00/third_party/include/openbsd.h
new/guest-oslogin-20230808.00/third_party/include/openbsd.h
--- old/guest-oslogin-20230502.00/third_party/include/openbsd.h 1970-01-01
01:00:00.000000000 +0100
+++ new/guest-oslogin-20230808.00/third_party/include/openbsd.h 2023-08-08
20:00:56.000000000 +0200
@@ -0,0 +1,242 @@
+/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */
+
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/net/base64.c */
+
+#ifndef _OPENBSD_H_
+#define _OPENBSD_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static char Base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+ The following encoding technique is taken from RFC 1521 by Borenstein
+ and Freed. It is reproduced here in a slightly edited form for
+ convenience.
+
+ A 65-character subset of US-ASCII is used, enabling 6 bits to be
+ represented per printable character. (The extra 65th character, "=",
+ is used to signify a special processing function.)
+
+ The encoding process represents 24-bit groups of input bits as output
+ strings of 4 encoded characters. Proceeding from left to right, a
+ 24-bit input group is formed by concatenating 3 8-bit input groups.
+ These 24 bits are then treated as 4 concatenated 6-bit groups, each
+ of which is translated into a single digit in the base64 alphabet.
+
+ Each 6-bit group is used as an index into an array of 64 printable
+ characters. The character referenced by the index is placed in the
+ output string.
+
+ Table 1: The Base64 Alphabet
+
+ Value Encoding Value Encoding Value Encoding Value Encoding
+ 0 A 17 R 34 i 51 z
+ 1 B 18 S 35 j 52 0
+ 2 C 19 T 36 k 53 1
+ 3 D 20 U 37 l 54 2
+ 4 E 21 V 38 m 55 3
+ 5 F 22 W 39 n 56 4
+ 6 G 23 X 40 o 57 5
+ 7 H 24 Y 41 p 58 6
+ 8 I 25 Z 42 q 59 7
+ 9 J 26 a 43 r 60 8
+ 10 K 27 b 44 s 61 9
+ 11 L 28 c 45 t 62 +
+ 12 M 29 d 46 u 63 /
+ 13 N 30 e 47 v
+ 14 O 31 f 48 w (pad) =
+ 15 P 32 g 49 x
+ 16 Q 33 h 50 y
+
+ Special processing is performed if fewer than 24 bits are available
+ at the end of the data being encoded. A full encoding quantum is
+ always completed at the end of a quantity. When fewer than 24 input
+ bits are available in an input group, zero bits are added (on the
+ right) to form an integral number of 6-bit groups. Padding at the
+ end of the data is performed using the '=' character.
+
+ Since all base64 input is an integral number of octets, only the
+ -------------------------------------------------
+ following cases can arise:
+
+ (1) the final quantum of encoding input is an integral
+ multiple of 24 bits; here, the final unit of encoded
+ output will be an integral multiple of 4 characters
+ with no "=" padding,
+ (2) the final quantum of encoding input is exactly 8 bits;
+ here, the final unit of encoded output will be two
+ characters followed by two "=" padding characters, or
+ (3) the final quantum of encoding input is exactly 16 bits;
+ here, the final unit of encoded output will be three
+ characters followed by one "=" padding character.
+ */
+
+int
+b64_pton(char const *src, u_char *target, size_t targsize)
+{
+ u_int tarindex, state;
+ int ch;
+ char *pos;
+
+ state = 0;
+ tarindex = 0;
+
+ while ((ch = *src++) != '\0') {
+ if (isspace(ch)) /* Skip whitespace anywhere. */
+ continue;
+
+ if (ch == Pad64)
+ break;
+
+ pos = strchr(Base64, ch);
+ if (pos == 0) /* A non-base64 character. */
+ return (-1);
+
+ switch (state) {
+ case 0:
+ if (target) {
+ if (tarindex >= targsize)
+ return (-1);
+ target[tarindex] = (pos - Base64) << 2;
+ }
+ state = 1;
+ break;
+ case 1:
+ if (target) {
+ if (tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 4;
+ target[tarindex+1] = ((pos - Base64) & 0x0f)
+ << 4 ;
+ }
+ tarindex++;
+ state = 2;
+ break;
+ case 2:
+ if (target) {
+ if (tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 2;
+ target[tarindex+1] = ((pos - Base64) & 0x03)
+ << 6;
+ }
+ tarindex++;
+ state = 3;
+ break;
+ case 3:
+ if (target) {
+ if (tarindex >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64);
+ }
+ tarindex++;
+ state = 0;
+ break;
+ }
+ }
+
+ /*
+ * We are done decoding Base-64 chars. Let's see if we ended
+ * on a byte boundary, and/or with erroneous trailing characters.
+ */
+
+ if (ch == Pad64) { /* We got a pad char. */
+ ch = *src++; /* Skip it, get next. */
+ switch (state) {
+ case 0: /* Invalid = in first position */
+ case 1: /* Invalid = in second position */
+ return (-1);
+
+ case 2: /* Valid, means one byte of info */
+ /* Skip any number of spaces. */
+ for (; ch != '\0'; ch = *src++)
+ if (!isspace(ch))
+ break;
+ /* Make sure there is another trailing = sign. */
+ if (ch != Pad64)
+ return (-1);
+ ch = *src++; /* Skip the = */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
+
+ case 3: /* Valid, means two bytes of info */
+ /*
+ * We know this char is an =. Is there anything but
+ * whitespace after it?
+ */
+ for (; ch != '\0'; ch = *src++)
+ if (!isspace(ch))
+ return (-1);
+
+ /*
+ * Now make sure for cases 2 and 3 that the "extra"
+ * bits that slopped past the last full byte were
+ * zeros. If we don't check them, they become a
+ * subliminal channel.
+ */
+ if (target && target[tarindex] != 0)
+ return (-1);
+ }
+ } else {
+ /*
+ * We ended by seeing the end of the string. Make sure we
+ * have no partial bytes lying around.
+ */
+ if (state != 0)
+ return (-1);
+ }
+
+ return (tarindex);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif