pkg/tools/ssl/openssl.go (93 lines of code) (raw):

// Licensed to Apache Software Foundation (ASF) under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Apache Software Foundation (ASF) licenses this file to you 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. package ssl import ( "fmt" "os/exec" "regexp" "strconv" "strings" "github.com/cilium/ebpf" ) var ( openSSLVersionRegex = regexp.MustCompile(`^OpenSSL\s+(?P<Major>\d)\.(?P<Minor>\d)\.(?P<Fix>\d+)\w?`) ) type OpenSSLSymbolAddresses struct { BIOReadOffset uint32 BIOWriteOffset uint32 FDOffset uint32 RoleOffset uint32 } func (r *Register) OpenSSL(symbolAddrMap *ebpf.Map, sslWrite, sslWriteRet, sslRead, sslReadRet *ebpf.Program) { r.addHandler("OpenSSL", func() (bool, error) { var libcryptoName, libsslName = "libcrypto.so", "libssl.so" var libcryptoPath, libsslPath string modules, err := r.findModules(libcryptoName, libsslName) if err != nil { return false, err } if len(modules) == 0 { return false, nil } if libcrypto := modules[libcryptoName]; libcrypto != nil { libcryptoPath = libcrypto.Path } if libssl := modules[libsslName]; libssl != nil { libsslPath = libssl.Path } if libcryptoPath == "" || libsslPath == "" { return false, fmt.Errorf("the OpenSSL library not complete, libcrypto: %s, libssl: %s", libcryptoPath, libsslPath) } addresses, err := r.buildOpenSSLSymAddrConfig(libcryptoPath) if err != nil { return false, err } if err := symbolAddrMap.Put(uint32(r.pid), addresses); err != nil { return false, err } libSSLLinker := r.linker.OpenUProbeExeFile(libsslPath) libSSLLinker.AddLink("SSL_write", sslWrite, sslWriteRet) libSSLLinker.AddLink("SSL_read", sslRead, sslReadRet) if err := r.linker.HasError(); err != nil { return false, err } return true, nil }) } func (r *Register) buildOpenSSLSymAddrConfig(libcryptoPath string) (*OpenSSLSymbolAddresses, error) { // using "strings" command to query the symbol in the libcrypto library result, err := exec.Command("strings", libcryptoPath).Output() if err != nil { return nil, err } for _, p := range strings.Split(string(result), "\n") { submatch := openSSLVersionRegex.FindStringSubmatch(p) if len(submatch) != 4 { continue } major := submatch[1] minor := submatch[2] fix := submatch[3] log.Debugf("found the libcrypto.so version: %s.%s.%s", major, minor, fix) conf := &OpenSSLSymbolAddresses{} // must be number, already validate in the regex majorVal, _ := strconv.Atoi(major) minorVal, _ := strconv.Atoi(minor) fixVal, _ := strconv.Atoi(fix) // max support version is 3.0.x if majorVal > 3 || (majorVal == 3 && minorVal > 0) { return nil, fmt.Errorf("the version of the libcrypto is not support: %s.%s.%s", major, minor, fix) } // bio offset // https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/ssl/ssl.h#L1093-L1111 // https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/ssl/ssl_local.h#L1068-L1083 // https://github.com/openssl/openssl/blob/openssl-3.0.7/ssl/ssl_local.h#L1212-L1227 conf.BIOReadOffset = 16 conf.BIOWriteOffset = 24 // fd offset if majorVal == 3 && minorVal == 0 { // 3.0.x // https://github.com/openssl/openssl/blob/openssl-3.0.7/crypto/bio/bio_local.h#L115-L128 // OPENSSL_NO_DEPRECATED_3_0 is not defined by default unless the user pass the specific build option conf.FDOffset = 56 // https://github.com/openssl/openssl/blob/openssl-3.0.7/ssl/ssl_local.h#L1212-L1245 conf.RoleOffset = 56 } else if (minorVal == 0) || (minorVal == 1 && fixVal == 0) { // 1.0.x || 1.1.0 // https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/crypto/bio/bio.h#L297-L306 conf.FDOffset = 40 // https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/ssl/ssl.h#L1093-L1138 conf.RoleOffset = 72 } else { // 1.1.1 // https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/crypto/bio/bio_local.h#L115-L125 conf.FDOffset = 48 // https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/ssl/ssl_local.h#L1068-L1101 conf.RoleOffset = 56 } log.Debugf("the lobcrypto.so library symbol verson config, version: %s.%s.%s, bio offset: %d", major, minor, fix, conf.FDOffset) return conf, nil } return nil, fmt.Errorf("could not fount the version of the libcrypto.so") }