Regular Expression to detect private and public RSA keys - regex

I've searched over the internet but with no results,
There is any pattern (to be implemented in regex) to detect RSA private or public keys ?
(not included strings such as ---- Public RSA key-- or "ssh rsa")
I'm stuck after create base64 regex
var re = regexp.MustCompile(`(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3})=`)
Thanks

Get pem formatted block
If your document contains not only PEM formatted block than Decode function from encoding/pem package will be helpful:
Decode will find the next PEM formatted block (certificate, private key etc) in the input. It returns that block and the remainder of the input. If no PEM data is found, p is nil and the whole of the input is returned in rest.
Parse key and check for rsa conformity
Go contains package named crypto to do such things like parsing keys and certifies. For purpose of parsing public keys provided function ParsePKIXPublicKey:
Supported key types include RSA, DSA, and ECDSA. Unknown key types result in an error.
On success, pub will be of type *rsa.PublicKey, *dsa.PublicKey, or *ecdsa.PublicKey.
On return you obtain concrete type which is easy to assert with type switch (idiomatic way to determine type of variable):
Example:
// There is a key
const pubPEM = `MIICIjANBgkqhkiG9...`
// Ignore the rest of document
block, _ := pem.Decode([]byte(pubPEM))
if block == nil {
log.Fatal("The document doesn't contain PEM blocks.")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal("The block is not a DER encoded public key.")
}
switch pub := pub.(type) {
case *rsa.PublicKey:
fmt.Println("pub is of type RSA:", pub)
default:
log.Fatal("The key is not RSA encripted.")
}

Related

problem to configure public key on google audit email api

I need a help! I'm trying to use the google auditing API (https://developers.google.com/admin-sdk/email-audit)
Im getting a problem to configure the public key on API (https://developers.google.com/admin-sdk/email-audit/auth#example), receiving the following error:
The value of attribute "value" associated with an element type "apps:property" must not contain the
'<' character.
Im following the documentation payload:
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<apps:property name="publicKey" value="<em>my public key in base64 here</em>"/>
</atom:entry>
One example of public key that i generated and encoded on base64:
LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptUUlOQkdJOW96c0JFQUNkTWlUajY2UUNJeTlOSjNzQzFGS1dlaFZDaTRKaGRtZDVhemtnMlh5WlM5RXNGT2hDCkJ6elVlT2lyRnRaKzR2c3pQZUdNT3A5eXlKS0dCcnk3ZUVWV0JzZTE0aHFzSjJiY1NRSEFOMnpVdDl6WlZNbzkKS3lBdGZxNytxTGRhNjhMbUpmM1drT1RxVFVCWnZ5OTQvYnhCMmR2UkR0ZWtCRFo2TlZIMVpObFJLOXY3Si90cgpNYmFvRnhiSmF4RlA4ZkZrVGxhcS9aY2ZCRmcxOWV0YkpHWUdTSU9yRlZ5MXVyQmlUOGx2TFhEbi81a2JNc0o1Cms3am5sUUNqcDcrN0RLSXVlSXBISGZBY2xNaitreEl4WmdlZElVbzJ0RTV3UVVIYmNmSU96a010UEFFWENUTUgKZW9GR2drTVBaaHB1NlhhbFY0RnlHZzdPMEtLWGcweHFtdjI3UDd1a0VlaFRkbzVLZitzZW5YZzVEbVpLQm9mRwoyejlzQUg1MXplWXZkVHhDSkdtdUprdWJPMEcvTFhxOHlGRW5oZEkyZjNkazQwNUZ4UlJna1BGU2tOYjFVS21mCklCSU1uM0VDVG1qK1JOWE9aS0Rqd2hmdHpkRS9KVGpueU1JVUFWR0VEWGtGdEVXTVRpSmIrVURZQi9odm9QS2sKdUNXNUNDNWtuOG14Z2x4eWxIaUVhQWJ6dTQ3MFBaaW9NTWo5VHk2VGZOVXZDOXJsRGszSEsreUpIaWJqWmxOagoxREdaN01yZWs4STV0ZVlVcmtZYVNDNUt4SVhSRjZwaEIyZUdUdzh5SEp3UUd3RURPL1E1QmJ3Q2dqREN4VS9ICkUyTFF4MURZeFU1Q1l4U1dIR0xzcVkrQUxKNGlsSXdNWEZERFZOdzRFVTl0Yis3cWdTajhXR2FRM1FBUkFRQUIKdEE1S2I4T2pieUJrWlNCQmMzTnBjNGtDVkFRVEFRZ0FQaFloQkJnbEtEbGhsVHFpUStRVUd2WFc5blJHV05JbQpCUUppUGFNN0Foc0RCUWtIaGg5eUJRc0pDQWNDQmhVS0NRZ0xBZ1FXQWdNQkFoNEJBaGVBQUFvSkVQWFc5blJHCldOSW1CbDRQL1JUeDlkbW1oMitXUE9jRUpGMXcvVkZqRFBMbkFWV3VSQnRKYmd2SVlETVdBUHpaTC9OYlRCL0wKUE1BYVdqdFlsRUZrZkpJMGxjdnU0L2F0R0JydDBIeGZFMW5FRjkzME5HcGNSaU80blcyd1hZSUhmaHg2ZnRlZwo3a283TDVPN21jMDgwWnpQRXQrSjEzZTZnSVdwbWExSXh3djRFRTVCb1NoQnpTOVlOWjNVQUJPLyszTnhCZHF2CloybldCcVR0cXpWb2Z4SGJPejBLRGJLclNLaUNmZy9EWmxzYVBES2FLMURQOU8xU3pJcURJWGQ0Q25RSWw2WUEKQjJPV0cvTE05OWV5Y2pxQitVTWw3ZzR4c1hBRGV1SG12SzVUSDUwRzgvRGpsSmZtWllkdUZiSm5hZGlHUnZWbApzOVpFNnZDRzl2ajNxQUFFVDhIcHNJUldTaWNGZHczVzFYV1RDdE1pYWE1M3ZidkhVaWw5QnI5VWxWMjJLbThkCmdLM3VsZXVCMmg4WnRXeEVIbE9kVXBDQ3RsNVp3RVBMeTNTSWIrL3lnQWV5cTAxanFOY0VlZmg1emk0VXNIZmQKdXZDVDZ0T0E2bmwyTVZuSDhzWTRHUlcrM0xqZjNJSVlRNzQ3QXQ3bGRVTDJCdTUrQng1bUlEV0QzZ0kvWnJ4LwpFQVU2QWx4eTI0YWJQcG90VlBYQW1BKzMzVDZsR2dWeXUwV2U3Vm14RkxucENmby8xQXlROUNWOVhIb1NhdjhmCkRJYXNtc203VnNaYXd1VTRoVi9DV2FPcXQ4WlUzRndyRDI0NElIR2c2L1RQZU1DWlRrMVhVdEVKdW9PcUpyb04KdDVXay8vZTI2VDh2akFWQWhHOWFzNE5HQnRLbUlDdlJpUkdEalEwQ1A2WEMzOVFEeEF3VnVRSU5CR0k5b3pzQgpFQURRNGl2bTQ2YTAzTXJZcUZjay90VWYxZTdCcTNtOVdVbkVOTEdtQ1RGdG1TTVJlQm5DZEx0bTV3K3piS1hLCmZMYzdrUTFNcHJMbTJVMk1zdk9XeGVjNk91eWxXeCtxOXB5UlR1NU5VR0txN1ZPUVZRYW9TNCs5VHpTQTBETmUKcUxjbWhIakhvSVNJZWVEZXRIWEZ1ZklNcHMvVUxCSndWUzZKYzdOaUhNNmp6TVMxS1hkVzJlbEFOdDdYNXBTYwpsLy9wL1VYTWxkSmZqZHMxWmljWFlkZWtGeTVyR3pHT2s4ZEhmMDRTS0Vsa1d0Ry9xZnZqb1FoVFRuOHZFTFZXCmpxUjlwS08yVDhDNXB1VFFwQld1Z0lGMFVaalAvcWVZL0xDMmVOcHNqczZ1SjllbU5GRXZ6YkJlSjlQOWhLUzQKdHUvZWxtSWFqczBPdFpycWMrTWNSQmFvcVVWQ1BETkFabVRWTnkyQ3l1MTFkQUJIRVozQWZBTE1qNXB4TmJiQgpHTWkxblByY3lqdzFOd05CV3VKTDdaQlZ6d2J3bjVQcHNlWVB5Vi93TWszd3RWNi9XVW9vdTYxbDI3RDdnY1lKCmlyYXN4R0pmSWR5WkNVSEFmNHNIN3MxM1VRb2puVHdodGlBWFpIaWlSTlBDVWF2VXFuSDVlZ3UrOElhKzZnTDkKeGE0cUI5a1lqc1cyem1LbTY4QkpLWGJKb1ZleGdOaVVnajYxZkphOC85UTJyQ2V5Y1VpdXRDbzFsUDFVQzhYMQplekNBNi8vL0hxQUxoU2ZuQ0hONHZRMzUvdlNGaHo3LzREbTBzSjI3Qk5leG0vQ1JFYXNBdVVYVWJFdXF4Q2VVCkZCMHVDTlo4cXkxT2FpWnl0cDFCaDBjYjlQWDdaSE9QQmpMeWpGaEZCak16RlFBUkFRQUJpUUk4QkJnQkNBQW0KRmlFRUdDVW9PV0dWT3FKRDVCUWE5ZGIyZEVaWTBpWUZBbUk5b3pzQ0d3d0ZDUWVHSDNJQUNna1E5ZGIyZEVaWQowaVpNT2cvK0kzejdnOElCWE81SThaNmY4cjhVcVpRNjE0dlkyUGtUSk1kK1c5SnZyTmFBWDJOdXBxMFk1ZjlLCkFiSTVCcjBaOFp1MjQ2NjVZZFQyUkNOS3VDa0dmZUc3WWlvTnhDREc2dys2c1o3SWtWQjBhcDJwYk8wb1ZBcFgKYzlWc3RzY2p2dkJheC91djgrZElGUmpKUithb21KRzFURVpVcWNvMEJVcHRXRUs3azN5SXAyUlBDVW5oeEcySQpZbUUwMmEwNkljdE9oeUtBUW9FM2ZRQmdLUGN6Z0tnbWNCdjhreDU4Qld1UEkyZk9MMjhQSm1jSzg5ZWpFdEwxCnRoNHh2dE9ibXl6SkFZTUduMHYyenpvV0NJUENGL2FIaVhpOEFvSEJRRExpeVpnejRla2Q0Q3B3TEtJUmJxYzQKZkkzOEgzQlQvQmxML3Bic0RHeXUvc2NVbUVsc3MrbnhrOWhkZVdwdCt2TTFGc2duN1RCY0FUb21zaVBVSG1obQpBUCsvdFRMVnNBb3FnMHpoanBaNVhBS28yUHVGZk42M2EvMGwxOXR2SmxGa09ZT0JEYVZKOWoxZmhuclBaSnJmCjJwODNLM1lhZ3hIWEQvNUFhVGNoM0Z5V2Nja3RmVDkyME5LY3AzUHNtZnN2bU5HdUYrRnlmYVpCQXh4MmtkWmgKTG13MEx6NVE3ME8wd1J4NnJZNmN0bHRvdnVlY29IS1VTWWdPamFsNzc3cG5tODRYb2FkdXdUdDVnUXlrdmlScwpiVHhZMytaWWM4eFJ1QjJYaTVkZGFUWkw2bEJoclpDMHdDWnI2L2hPYTVhUFdVVStGeFdtZkpsZ3A0Z1VkeVIwCldkK1FOMXNMZmt0b2Y5amJXeFRwNjd5SUpBMDV6c2VpdUp4OEszTmxDWk80YTN1T2xuUT0KPWZmZWsKLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQ==
If you check on base64 decode for example, you can see that its a complete public key...
Any idea?
Thank you!
The error message points that there is a non valid character being passed on the "value" attribute, in this case the <> characters are non valid within the value field, checking your example you are adding it like this:
<apps:property name="publicKey" value="<em>my public key in base64 here</em>"/>
Where the "value=<em>my public key in base64 here</em>" is being passed with the "<>" characters, even though the documentation states that "<em>" and "</em>" is passed you can still just remove the tags and add the public key without them like this:
<apps:property name="publicKey" value="my public key in base64 here"/>

Invalid Hash Function Name on SHA2-512 when creating user

Trying to create user using from golang using library "google.golang.org/api/admin/directory/v1"
As docs sad here https://developers.google.com/admin-sdk/directory/reference/rest/v1/users#User hashFunction could be MD5, DES, SHA2-256, SHA2-512, so i'm writing code:
hash := sha512.Sum512([]byte("random password value))
encoded := hex.EncodeToString(hash[:])
payload := &admin.User{
Password: "$6$" + encoded,
HashFunction: "SHA2-512"
}
This results: googleapi: Error 400: Invalid Hash Function Name, invalid
So how to understand, whats wrong with hash function name ?
So, i found here https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/python/latest/admin_directory_v1.users.html#insert that right now only supported SHA-1, crypt and MD5, so documentation is wrong, and for SHA2 hashes use string "crypt" as hashFunction value and add to password corresponding crypt prefix ( for example for SHA2-512 add $6$ to hex encoded value )

NEAR FunctionCall `args` field

In the near_primitives::views, the args field on the FunctionCall is represented as a String type. From the chain data model, which is transaction::Action::FunctionCall, its args field there is a `Vec.
The question is, does this args field will always content a valid JSON payload as the content? We assume the answer is probably a No since the underlying field contains pure bytes.
In which circumstances this would a valid JSON string and in which circumstances it would be a binary format?
Finally, if binary format is possible (likely), how is it possible to decode it? Is this in developers hand and could be any binary format?
See
https://github.com/near/nearcore/blob/14711926391d3ec1d23116658a295a62e77bc701/core/primitives/src/views.rs#L768
https://github.com/near/nearcore/blob/14711926391d3ec1d23116658a295a62e77bc701/core/primitives/src/transaction.rs#L113
In most cases args will be base64 encoded JSON string.
Here's an example of how we decode them on NEAR Indexer for Explorer side.
ActionView::FunctionCall {
method_name,
args,
gas,
deposit,
} => {
if let Ok(decoded_args) = base64::decode(args) {
if let Ok(mut args_json) = serde_json::from_slice(&decoded_args) {
escape_json(&mut args_json);
arguments["args_json"] = args_json;
}
}
Is this in developers hand and could be any binary format?
Yes.
Rainbow Bridge-related transactions have borsh-serialized args which are not possible to decode into JSON.
ref: https://github.com/near/near-indexer-for-explorer/blob/master/src/models/serializers.rs#L94-L103
args are not limited to any format at all, they are just binary blob. What you see in the views.rs is partially serialized data where args are expected to be in base64 encoding thus it is a String (thus, it is always base64 data there; be it JSON, Borsh-serialized data, or just raw binary blob, e.g. PNG image)

How to parse SubjectDirectoryAttributes Extension with OpenSSL?

How can I read the X509 Certificate Extension: Subject Directory Attributes with OpenSSL in C++?
My Certificate contains the SubjectDirectoryAttributes-Extension with the following Attributes:
OID : Value
-------------------------------------------------------------------
(1.3.6.1.5.5.7.9.4) countryOfCitizenship : DE
(1.3.6.1.5.5.7.9.3) gender : F
(1.3.6.1.5.5.7.9.1) dateOfBirth : 1971-10-14 12:00:00 UTC
(1.3.6.1.5.5.7.9.2) placeOfBirth : Darmstadt
So i want to get these pairs of OID and Value.
I found no Struct like SUBJECT_DIRECTORY_ATTRIBUTES in the Source-Code I can use. I got the Extension this way:
int loc = X509_get_ext_by_NID(certificate, NID_subject_directory_attributes, -1);
X509_EXTENSION *ex = X509_get_ext(certificate, loc);
But how can I get then all the data, which means all the OIDs and Values to the OIDs? The ASN.1 Structure is:
SubjectDirectoryAttributes ::= Attributes
Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
Attribute ::= SEQUENCE
{
type AttributeType
values SET OF AttributeValue
}
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= ANY DEFINED BY AttributeType
I found out that I get a custom extension with: X509_EXTENSION_get_object(ex) and that the OpenSSL-Type X509_NAME_ENTRY is the equvivalent to the ASN.1-Structure Attribute resp. AttributeTypeAndValue.
So i tried to cast the result of X509_EXTENSION_get_data(ex) to a STACK_OF(X509_NAME_ENTRY) and to X509_NAME. But X509_NAME is the same as STACK_OF(X509_NAME_ENTRY).
Then I tried to get the number of attributes by calling the sk_X509_NAME_ENTRY_num() function on the STACK_OF(X509_NAME_ENTRY) resp. X509_NAME.entries, but I got not the right number.
I expect to get the number 3 or 4 (don't know the exactly internal counting - but the example cert contains 4 Attributes, so the output should be 3 or 4 depending if the counting will start at 0 or 1).
But instead of 3 or 4 I got a much larger number like 34335029 and this number is different every time I run the code. So I think there is a problem with the casting or I did not choose the right Data-Type(s).
I'm using OpenSSL 1.0.2j.
So what's wrong and how can I fix it?
Here a short excerpt of my code:
X509_EXTENSION *ex = ....
STACK_OF(X509_NAME_ENTRY) *st = (STACK_OF(X509_NAME_ENTRY)*) X509_EXTENSION_get_data(ex);
printf(sk_X509_NAME_ENTRY_num(st));
// or alternative
X509_Name *name = (X509_Name*) X509_EXTENSION_get_data(ex);
printf(sk_X509_NAME_ENTRY_num(name.entries));
Here I append the certificate if you need it. It's from the RFC specification:
-----BEGIN CERTIFICATE-----
MIIDEDCCAnmgAwIBAgIESZYC0jANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQGEwJE
RTE5MDcGA1UECgwwR01EIC0gRm9yc2NodW5nc3plbnRydW0gSW5mb3JtYXRpb25z
dGVjaG5payBHbWJIMB4XDTA0MDIwMTEwMDAwMFoXDTA4MDIwMTEwMDAwMFowZTEL
MAkGA1UEBhMCREUxNzA1BgNVBAoMLkdNRCBGb3JzY2h1bmdzemVudHJ1bSBJbmZv
cm1hdGlvbnN0ZWNobmlrIEdtYkgxHTAMBgNVBCoMBVBldHJhMA0GA1UEBAwGQmFy
emluMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc50zVodVa6wHPXswg88P8
p4fPy1caIaqKIK1d/wFRMN5yTl7T+VOS57sWxKcdDzGzqZJqjwjqAP3DqPK7AW3s
o7lBG6JZmiqMtlXG3+olv+3cc7WU+qDv5ZXGEqauW4x/DKGc7E/nq2BUZ2hLsjh9
Xy9+vbw+8KYE9rQEARdpJQIDAQABo4HpMIHmMGQGA1UdCQRdMFswEAYIKwYBBQUH
CQQxBBMCREUwDwYIKwYBBQUHCQMxAxMBRjAdBggrBgEFBQcJATERGA8xOTcxMTAx
NDEyMDAwMFowFwYIKwYBBQUHCQIxCwwJRGFybXN0YWR0MA4GA1UdDwEB/wQEAwIG
QDASBgNVHSAECzAJMAcGBSskCAEBMB8GA1UdIwQYMBaAFAABAgMEBQYHCAkKCwwN
Dg/+3LqYMDkGCCsGAQUFBwEDBC0wKzApBggrBgEFBQcLAjAdMBuBGW11bmljaXBh
bGl0eUBkYXJtc3RhZHQuZGUwDQYJKoZIhvcNAQEFBQADgYEAj4yAu7LYa3X04h+C
7+DyD2xViJCm5zEYg1m5x4znHJIMZsYAU/vJJIJQkPKVsIgm6vP/H1kXyAu0g2Ep
z+VWPnhZK1uw+ay1KRXw8rw2mR8hQ2Ug6QZHYdky2HH3H/69rWSPp888G8CW8RLU
uIKzn+GhapCuGoC4qWdlGLWqfpc=
-----END CERTIFICATE-----
Since OpenSSL has no direct support in the crypto libary there is no built in code for parsing this extension. I have either to wait for official support or implement the whole thing by myself.

convert STACK_OF(X509) to ASN1 stream

first of all: Sorry for my bad english. I hope you can understand me.
I using OpenSSL 1.0.2 and I have some problems with it. I have a STACK_OF(X509) object with three certificates and I want to convert this stack to an ASN1 object (like OCTET STRING or ANY). Is this possible? I use an external asn.1 library and not OpenSSL-ASN1. So I need the data as unsigned char (raw binary or DER encoded).
I can convert a single certificate via i2d_X509() into DER format. This is good, but I want the complete stack. This is my goal:
myAsn1Data ::= sequence {
... -- (some ASN.1 data)
... -- (some ASN.1 data)
ANY -- contain the DER encoded STACK_OF(X509)....somehow
}
But possibly is this the right way (ASN.1 syntax):
stackOfX509 ::= SEQUENCE_Of {
TBSCertificate
}
or like this:
stackOfX509 ::= SET_OF {
ANY -- contain a DER encoded X509 certificate
}
I hope someone can help me.
People normally do one of two things for this.
1) "Cheat"! If the DER encoded representation of the certificate is available but the original schema for it is not, simply have an OCTET STRING to store the bytes.
myAsn1Data ::= SEQUENCE {
..., -- (some ASN.1 Data)
..., -- (some ASN.1 Data)
cert [2] OCTET STRING -- (the DER bytes would go in this field)
}
and the flow of your application code would be something like
myAsn1Data data = new(myAsn1Data);
data.cert = readbytesfromfile(certificatefile);
data.something = 10;
data.else = 20;
asn1encode(data, outputfile)
2) Acquire the original schema for an X509 certificate. It ought to be in here somewhere, looks like section 7.2. With this the source your ASN.1 compiler will create for you should be able to decode the certificate, allowing you to place it inside an instance of your myAsn1Data.
IMPORTS Certificate FROM <ITU's X509 Schema file>
CertificateStack ::= SEQUENCE of Certificate
myAsn1Data ::= SEQUENCE {
..., -- (some ASN.1 Data)
..., -- (some ASN.1 Data)
cert [2] CertificateStack
}
and the sequences in your application code would look something like this:
Certificate cert1 = asn1decode(certificatefile);
Certificate cert2 = asn1decode(anothercertificatefile);
Certificate cert3 = asn1decode(yetanothercertificatefile);
CertificateStack stack;
stack.push_back(cert1);
stack.push_back(cert2);
stack.push_back(cert3);
myAsn1Data data = new(myAsn1Data);
data.cert = stack;
data.something = 10;
data.else = 20;
asn1encode(data, outputfile)
This way is better because it completely defines what the 'cert' field actually is. The first way isn't quite so good if you are exchanging data with someone else because they need to be told what the cert field actually is.